ScrollToItem /Bottom

10 posts, 0 answers
  1. Julian
    Julian avatar
    17 posts
    Member since:
    Aug 2015

    Posted 21 Mar Link to this post

    Hey guys,

    I am currently implementing a custom renderer for my xamarin.forms ios application. I want to scroll to the bottom of the Listview but currently I don't see a way to do this.

    I tryed to use the "ScrollToItem" method, but to use this method i need the indexpath of the last cell in my Listview and I don't know how to get this.

    could you help me to solve this problem?

     

    Best regards

    Julian

  2. Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    419 posts

    Posted 21 Mar Link to this post

    Hello Julian,

    You can get an array of the indexPaths for items in the RadListView's visible items using this property (or this one if you want the indexPath of the selected items).

    Ultimately, to get the indexPath for any cell, you can use getIndexPathForCell.

    Once you get the indexPath on the last cell in your RadListView, then you can call scrollToItemAtIndexPath.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Julian
    Julian avatar
    17 posts
    Member since:
    Aug 2015

    Posted 22 Mar Link to this post

    Hey Lance and thanks for your fast reply.

    In my case IndexPathsForVisibleItems doesn't contain any items.

    My code looks like this, am I doing anything wrong?

    Best regards

    Julian

    public class MyListViewRenderer : Telerik.XamarinForms.DataControlsRenderer.iOS.ListViewRenderer
        {
            public ChatList View = new ChatList();
     
            protected override void OnElementChanged(Xamarin.Forms.Platform.iOS.ElementChangedEventArgs<Telerik.XamarinForms.DataControls.RadListView> e)
            {
                base.OnElementChanged(e);
     
                if (e.NewElement != null) {
                    View = e.NewElement as ChatList;
                   View.Scroll += MyListViewRenderer_Scroll;
                }
     
            }
     
     
            public override bool AccessibilityScroll(UIAccessibilityScrollDirection direction)
            {
                return base.AccessibilityScroll(direction);
     
            }
            private void MyListViewRenderer_Scroll(object sender, EventArgs e)
            {
                if (Control.IndexPathsForVisibleItems.Count() > 0)
                {
                    var a = Control.IndexPathsForVisibleItems.LastOrDefault();
                    Control.ScrollToItem(a, UICollectionViewScrollPosition.Bottom, false);
                }
            }
        }
  4. Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    419 posts

    Posted 22 Mar Link to this post

    Hello Julian,

    With what you've provided for code, it looks functional. I would put a breakpoint or Debug.WriteLine, inside the if statement to ensure that the a variable has a valid value.

    However, there is a problem with your approach of using the visible items. You'll never be able to get the last item in the unless the user happens to already be at the bottom.

    Instead, you could just create the indexPath manually, like this (I use 49 so that it scrolls to the 50th item, but you can pass it the total number of items, minus 1):

    var ip = NSIndexPath.Create(0,49);
                     
    Control.ScrollToItem(ip, UICollectionViewScrollPosition.Top, true);

    To help, I've attached a demo that is based off your code.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  5. Julian
    Julian avatar
    17 posts
    Member since:
    Aug 2015

    Posted 29 Mar Link to this post

    Hey Lance, 

    thank you for your example! 

    In my app the Listview is scrolling but not to the End. May it be connected to the fact that i have a dynamic rowheight?

     

    Best regards

    Julian

  6. Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    419 posts

    Posted 03 Apr Link to this post

    Hello Julian,

    I can't tell what's wrong with your specific implementation without a reproducible to debug directly.

    You can try a slightly different approach that also take into account the number of groups and number of items in each group.

    Here's the full implementation:

    1 - Define the renderer's interface in the portable project:

    public interface ICustomListViewRenderer
    {
        void ScrollTo(int index, int section);
     
        int NumberOfGroups();
     
        int NumberOfItemsInGroup(int group);
    }


    2 - Define the custom RadListView in the portable project:

    public class CustomRadListView : RadListView
    {
        public ICustomListViewRenderer Renderer { get; set; }
     
        public void ScrollTo(int index, int group)
        {
            Renderer?.ScrollTo(index, group);
        }
     
        public int NumberOfGroups()
        {
            return Renderer?.NumberOfGroups() ?? 0;
        }
     
        public int NumberOfItemsInGroup(int group)
        {
            return Renderer?.NumberOfItemsInGroup(group) ?? 0;
        }
    }


    3 - In the iOS project, implement the interface:

    public class CustomListViewRenderer : ListViewRenderer, ICustomListViewRenderer
        {
            public int NumberOfGroups()
            {
                return (int)(this.Control?.NumberOfSections ?? 0);
            }
     
            public int NumberOfItemsInGroup(int group)
            {
                return (int)(this.Control?.NumberOfItemsInSection(group) ?? 0);
            }
     
            public void ScrollTo(int index, int group)
            {
                if (group < NumberOfGroups() && index < NumberOfItemsInGroup(group))
                {
                    var indexPath = NSIndexPath.FromItemSection(index, group);
                    this.Control.ScrollToItem(indexPath, UICollectionViewScrollPosition.Top, true);
                }
            }
     
            protected override void OnElementChanged(Xamarin.Forms.Platform.iOS.ElementChangedEventArgs<Telerik.XamarinForms.DataControls.RadListView> e)
            {
                base.OnElementChanged(e);
     
                var oldElement = e.OldElement as CustomRadListView;
                if (oldElement != null)
                {
                    oldElement.Renderer = null;
                }
     
                var newElement = e.NewElement as CustomRadListView;
                if (newElement != null)
                {
                    newElement.Renderer = this;
                }
            }
        }



    Here's an example of using it in a Xamarin Forms's view

    public MainPage()
    {
        var lv = new CustomRadListView { ItemsSource = Enumerable.Range(0, 1000) };
        var btn = new Button { Text = "scroll" };
     
        btn.Clicked += (sender, e) =>
        {
            lv.ScrollTo(50, 0);
        };
     
        var grid = new Grid
        {
            RowDefinitions = new RowDefinitionCollection {
                        new RowDefinition { Height = GridLength.Star },
                        new RowDefinition { Height = GridLength.Auto }
            }
        };
     
        grid.Children.Add(lv, 0, 0);
        grid.Children.Add(btn, 0, 1);
     
        this.Content = grid;
    }


    Regards,
    Lance | Tech Support Engineer, Sr.
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  7. Julian
    Julian avatar
    17 posts
    Member since:
    Aug 2015

    Posted 11 Apr Link to this post

    Hey Lance, 

    I uploaded an example Project where you can see how I use the ListView.

    https://www.file-upload.net/download-12432750/TestProj.zip.html

    There you can reproduce my scrollproblem.

     

    Best regards

    Julian

  8. Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    419 posts

    Posted 12 Apr Link to this post

    Hello Julian,

    Thank you for preparing a repro project. Unfortunately, that site you used to upload it to is laden with malicious attacks and I cannot safely download it.

    I have prepared this folder for you to upload the project to (for security reasons, I've set the expiration of that link for a couple days because this is a public forum).

    Once you've uploaded it, come back here and let me know. I'll then take a look and see what I can do to improve the RadlistView experience.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  9. Julian
    Julian avatar
    17 posts
    Member since:
    Aug 2015

    Posted 13 Apr Link to this post

    I uploaded my Testproject to your folder. 
    To get it run you need to add the Telerik .dll since I removed it for posting the project.

    Thanks alot for your support Lance!

    Julian

  10. Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    419 posts

    Posted 13 Apr Link to this post

    Hi Julian,

    Thank you for sharing the project, however it is not buildable. You have several problems with your project references (other than removing the Telerik one). For, example one of the references has a hard path to the Packages folder instead of letting Nuget handle the project references.

    Looking at the code, I have a couple comments

    It looks like you did not apply the approach I showed in my last reply that takes into account groups, this part of the renderer determines the indexPath using both the item index as well as the group

    var indexPath = NSIndexPath.FromItemSection(index, group);


    You have a little more control over the placement of the item when it's scrolled. See the Control.ScrollToItem() method in the renderer

    this.Control.ScrollToItem(indexPath, UICollectionViewScrollPosition.Top, true);


    Regards,
    Lance | Tech Support Engineer, Sr.
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top