Listview inside Scrollview

ChethanChethan USMember ✭✭
edited April 2013 in Xamarin.Android

I am having trouble with scrolling listview inside a scrollview. I am having an activity which looks like,
(linearLayout)
(scrollView)
(LinearLayout)
Loooooooong Text
(ListView /)
(button)
(button)
(imageview)
(/LinearLayout)
(/ScrollView)
(/LinearLayout)

Using a ScrollView to scroll through the long text, the ListView breaks.Is there anything i can do?

Best Answer

Answers

  • IvanHarrisIvanHarris USMember ✭✭✭

    Try to take out the first linearlayout... have the scrollview the main layout. Try that.

  • RodyRody USMember ✭✭

    Thanks @maulik25it . That is the perfect solution because it gives the listview in Android the same behavior that it already has in iOS.

  • rzee7rzee7 INUniversity ✭✭✭✭✭

    Hey @Rody

    Please accept @maulik25it answer if you find helpful for your problem. It will help others to see exact solution.

    Thanks
    {rzee}

  • AditkothariAditkothari USMember ✭✭

    @maulik25it Wah sir this is the perfect solution I was looking for...Great...Thank You Once again

  • maulik25itmaulik25it INMember ✭✭
    edited December 2016

    Thanks @Aditkothari

  • mikoomikoo DKMember ✭✭

    @PhilRyan said:
    I found @DougW's answer (for Java) on StackOverflow stackoverflow.com/a/3495908/3540849 worked well enough, once translated into C#. The following is a complete codefile, including the Using statements that I found were necessary:

    using System;
    using System.Linq;
    using Android.Views;
    using Android.Widget;
    
    namespace WhateverNamespaceYouChoose
    {
      public class Utility
      {
          public static void setListViewHeightBasedOnChildren (ListView listView)
          {
              if (listView.Adapter == null) {
                  // pre-condition
                  return;
              }
    
              int totalHeight = listView.PaddingTop + listView.PaddingBottom;
              for (int i = 0; i < listView.Count; i++) {
                  View listItem = listView.Adapter.GetView (i, null, listView);
                  if (listItem.GetType () == typeof(ViewGroup)) {
                      listItem.LayoutParameters = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
                  }
                  listItem.Measure (0, 0);
                  totalHeight += listItem.MeasuredHeight;
              }
    
              listView.LayoutParameters.Height = totalHeight + (listView.DividerHeight * (listView.Count - 1));
          }
      }
    }
    

    Works like a charm!!!11 one one

  • ShimmyWeitzhandlerShimmyWeitzhandler USMember ✭✭✭

    Anything about the XF ListView?

  • MichelangeloFrancoMichelangeloFranco ITUniversity ✭✭

    @maulik25it Thanks, works like a charms, You resolved my problem...

  • coco90coco90 USMember ✭✭

    Hi @maulik25it, this solution not work for Android 4.4!!
    Do you have a solution?
    Thanks

  • IeuanWalkerIeuanWalker USMember ✭✭

    @maulik25it perfect answer thanks a lot :smile:

  • DerProgrammiererDerProgrammierer DEMember ✭✭✭
    edited June 2018

    @maulik25it said:
    You can simply do with set 'NestedScrollingEnabled' property true for native side.
    For xamarin forms you can create a custom renderer and set 'NestedScrollingEnabled' property true

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
    
            if (e.NewElement != null)
            {
                var listView = this.Control as Android.Widget.ListView;
                listView.NestedScrollingEnabled = true;               
            }            
        }
    

    Problem with this is that it only works for API >= 21. The app will crash if you run this code on a device with API <= 21.

    Instead, use this CustomRenderer for Android. This works for all API levels:

    public class OneListViewRenderer : ListViewRenderer
    {
        public OneListViewRenderer(Context context) : base(context)
        {
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
    
            if (e.OldElement != null)
            {
                Control.Touch -= Control_Touch;
            }
    
            if (e.NewElement != null)
            {
                Control.Touch += Control_Touch;
            }
    
            this.Control.SetSelector(Resource.Drawable.list_item_selector);
        }
    
        private void Control_Touch(object sender, TouchEventArgs e)
        {
            switch(e.Event.Action)
            {
                case MotionEventActions.Down:
                    // Disallow ScrollView to intercept touch events.
                    this.Parent.RequestDisallowInterceptTouchEvent(true);
                    break;
    
                case MotionEventActions.Up:
                    // Allow ScrollView to intercept touch events.
                    Parent.RequestDisallowInterceptTouchEvent(false);
                    break;
            }
    
            Control.OnTouchEvent(e.Event);
        }
    }
    

    What this does is disable the TouchEvents on the ScrollView and make the ListView intercept them. It is simple and works all the time.

    Credit: https://stackoverflow.com/a/14577399/4825351

  • rhunojarhunoja Member

    In order to full expand a listview inside a scrollview no matter how many items it has, you can use MVVM setting up a property autocalculated "int ListviewCount" in a ViewModel executedCommand, then Binding this property in the HeightRequest from a StackLayout that content your ListView.

  • @rhunoja can you explaint this a little more please

  • BhautikBhautik Member ✭✭✭

    @maulik25it said:
    You can simply do with set 'NestedScrollingEnabled' property true for native side.
    For xamarin forms you can create a custom renderer and set 'NestedScrollingEnabled' property true

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
    
            if (e.NewElement != null)
            {
                var listView = this.Control as Android.Widget.ListView;
                listView.NestedScrollingEnabled = true;               
            }            
        }
    

    Thanks,Perfect solution. :)
    But what about iOS?

Sign In or Register to comment.