ListView is not scrolling when main activity has scrollview

Hi,
I have Activity with Listview.
when i populate the Listview via SimpleCursorAdapter.
then only i can scroll the whole activity or ListView.
how to scroll both.
i have attached my code !

Posts

  • CheesebaronCheesebaron DKInsider, University mod

    Sounds like you have a ListView inside a ScrollView. That won't work well as both have scroll handlers. Loads of answers for that on your favorite search engine, and I believe it has been asked in here too as well.

    Btw. no one wants your full source code, just post the relevant code snippets instead. Saves us the hassle of having to dig through your code, and download untrusted files, etc.

  • alinjojobaalinjojoba INMember ✭✭

    I Solved !
    private void fillGridView()
    {
    SimpleCursorAdapter _hesabMoenGridAdapter = new HesabMoenGridView(this, Resource.Layout.HesabMoenGrid, cursor, from, to);

                        gvHesabMoen.Adapter = _hesabMoenGridAdapter;
    
                        //gvHesabMoen.Touch += gvHesabMoen_Touch;
                        setListViewHeightBasedOnChildren(gvHesabMoen);
    

    }
    public void setListViewHeightBasedOnChildren(ListView listView)
    {
    try{
    SimpleCursorAdapter listAdapter = (SimpleCursorAdapter)listView.Adapter;
    if (listAdapter == null)
    {
    // pre-condition
    return;
    }

            int totalHeight = 0;
            for (int i = 0; i < listAdapter.Count; i++)
            {
                View listItem = listAdapter.GetView(i, null, listView);
                listItem.Measure(0, 0);
                totalHeight += listItem.MeasuredHeight;
            }
    
            ViewGroup.LayoutParams _params = listView.LayoutParameters;
    
                 _params.Height = totalHeight + (listView.DividerHeight * (listAdapter.Count - 1));
                 if (_params.Height < 250)
                     _params.Height = 250;
              listView.LayoutParameters = _params;
              listView.RequestLayout();
            }
            catch (Exception ex)
            {
                MessageBoxAndroid.Show(this, "scrollings\n" + ex.Message + "\n StackTrace :\n" + ex.StackTrace);
            }
        }
    

    -------------------------------Layout----------------------------------------------------


      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
                      android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true"
                    android:background="#488ce9"
                  >  
    

        <!--#endregion-->
    
    
    
      </LinearLayout>
    </HorizontalScrollView>
    
    <!--</RelativeLayout>-->
    


    END


  • alinjojobaalinjojoba INMember ✭✭

    Hi,
    But how to use this in monodroid (C#)??

  • alinjojobaalinjojoba INMember ✭✭
    edited December 2013

    This is for Android (C#) :

    fillListView() 
    { 
    SimpleCursorAdapter _Adapter = new HesabMoenListView(this, Resource.Layout.HesabMoenList, cursor, from, to);
    
    gvHesabMoen.Adapter = _Adapter;
    
    //Just one of bellow codes should be use !
    
    gvHesabMoen.Touch += gvHesabMoen_Touch;// each have seperate Scrolling ...
    setListViewHeightBasedOnChildren(gvHesabMoen);//both have one Scrolling ..
    
    }
    
    

    and the events are :

    Then attention : Just one of these code should be use !

    1.For setListViewHeightBasedOnChildren :

    public void setListViewHeightBasedOnChildren(ListView listView)
            {
                 try{
                    SimpleCursorAdapter listAdapter = (SimpleCursorAdapter)listView.Adapter;
                if (listAdapter == null)
                {
                    // pre-condition
                    return;
                }
                 
                int totalHeight = 0;
                for (int i = 0; i < listAdapter.Count; i++)
                {
                    View listItem = listAdapter.GetView(i, null, listView);
                    listItem.Measure(0, 0);
                    totalHeight += listItem.MeasuredHeight;
                }
                  
                ViewGroup.LayoutParams _params = listView.LayoutParameters;
                 
                     _params.Height = totalHeight + (listView.DividerHeight * (listAdapter.Count - 1));
                     if (_params.Height < 250)//to have min height
                         _params.Height = 250;//to have min height
                  listView.LayoutParameters = _params;
                  listView.RequestLayout();
                }
                catch (Exception ex)
                {
                    
                }
            }
    
    

    2.For Touch :

    public void gvHesabMoen_Touch(object sender, View.TouchEventArgs e)
            {
                switch (e.Event.Action)
                {
                    case MotionEventActions.Down:
                        gvHesabMoen.Parent.RequestDisallowInterceptTouchEvent(true);
                        break;
                    case MotionEventActions.Up:
                        gvHesabMoen.Parent.RequestDisallowInterceptTouchEvent(false);
                        break;
                }
    
                gvHesabMoen.OnTouchEvent(e.Event);
                        }
    
    

    and finally the Layout :

    is in Next Post

  • alinjojobaalinjojoba INMember ✭✭
    edited December 2013
    Note : the layout is same for both of codes !!!!!



      <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"

                      android:layout_width="match_parent"

                      android:layout_height="match_parent"

                >

        <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"

        android:id="@+id/hm_scroll"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:fadeScrollbars="false"

        android:layout_gravity="right"

           android:background="#488ce9"

    >

          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="fill_parent"

              android:layout_height="fill_parent"

                          android:descendantFocusability="beforeDescendants"

        android:focusableInTouchMode="true"

                        android:background="#488ce9"

                      >

            <TableLayout

             android:minWidth="25px"

             android:minHeight="25px"

             android:layout_width="fill_parent"

             android:layout_height="wrap_content"

             android:layout_gravity="center_horizontal"

             android:id="@+id/tableLayout1"

             android:stretchColumns="*"

                       >

              <TableRow

                        android:id="@+id/tableRow3"

                        android:layout_width="wrap_content"

                        android:background="#669cb7"

                        android:paddingLeft="2550px"

              >

                <LinearLayout

           android:id="@+id/navigationLayout3"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:layout_gravity="left"

           android:background="#669cb7"

           android:orientation="horizontal">

                  <Button

                            android:id="@+id/btnhm_NameHesab"

                            android:layout_width="50dp"

                            android:layout_height="41dp"

                            android:gravity="center|center_vertical|center_horizontal"

                            android:background="@drawable/btnSelect"

                            android:layout_marginTop="4dp"

                 />



                  <EditText

                        android:layout_marginLeft="15dp"

                      android:layout_width="500px"

                      android:layout_height="50dp"

                      android:id="@+id/txthm_NameHesab"

                      android:nextFocusDown="@+id/txthm_CodeHesab"

                      android:imeOptions="actionNext"

                      android:paddingRight="110dp"

                      android:paddingLeft="17dp"

                       android:paddingTop="11dp"

                      android:background="@drawable/HesabName"

                      android:ellipsize="start"

                      android:gravity="right"

                      android:singleLine="true"

                      android:layout_marginTop="4dp"

                 />

                             </LinearLayout>

              </TableRow>

    </TableLayout>

    <ListView

                    android:minWidth="25px"

                    android:minHeight="250dp"

                    android:layout_width="fill_parent"

                    android:layout_height="500dp"

                    android:fastScrollEnabled="true"

                    android:id="@+id/gvHesabMoen"

                    android:paddingBottom="20dip"

                    android:clipToPadding="false"

                  />

     </LinearLayout>

        </HorizontalScrollView>

      </ScrollView>

  • RobCrossleyRobCrossley USMember ✭✭✭

    My answer is written in C#. That's what I'm using in Xamarin right now to overcome this same issue actually.

  • Eclipsed4utooEclipsed4utoo USMember ✭✭

    Thanks @RobCrossley‌ . After searching for a fix to this issue and finding all the "don't do it" posts and the "use a linear layout instead" posts, your code worked perfectly.

  • MattFaraMattFara CAMember

    @RobCrossley your solution seems to be working but my ListView is only as big as a single Item. How can I get the ListView to span it's entire length?

  • RobCrossleyRobCrossley USMember ✭✭✭

    @MattFara‌ I haven't found a really good way to do that using a list view. Even if you set it to wrap content, or even use a weight of 1 (with linear layouts), it never seems to take fill up just what it needs.

    That being said, and adding an alternative to this solution, there's another way you can go about this. What you can do is add an empty layout, preferably a linear layout (vertical) for simplicity's sake. Create your list of objects, and pass it to your adapter, then loop through that list and retrieve the views and simply add them one by one to the linear layout. Here's a brief example of how to accomplish that:

        //Populating the list I'm going to hand to my adapter
        list<ContactDetail> contactDetails = new list<ContactDetail>(DatabaseManager.Instance.GetContactDetails());
    
        //Mine is in a fragment, so I'm using Activity as the context, just replace Activity with "this" if this is in an activity, and
       //obviously replace this adapter and list with your own
        ContactDetailAdapter adapter = new ContactDetailAdapter (Activity, contactDetails);
    
        //This is the empty LinearLayout in my axml file.  dispositionLayout is of type LinearLayout
        dispositionLayout = view.FindViewById<LinearLayout> (Resource.Id.linearLayoutDispositions);
    
        //If you're ever going to be repopulating the data in your fragment or activity, it's good to call this, as it'll just remove
       //all views you've previously added
        dispositionLayout.RemoveAllViews ();
    
        //Loop through your list that you handed to the adapter
        foreach (ContactDetail cd in contactDetails) {
    
                    //This retrieves the view for that particular object.  container is the ViewGroup.  You can snag this by overriding 
                    //the OnCreateView method and just saving an instance of the view group:
                   //public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                   // this.container = container;  //etc.
                var cdView = adapter.GetView (contactDetails.IndexOf (cd), null, container);
    
                    //Since you're not using a list view, you can add your own click events here so that it reacts when you tap on
                    //Individual items.  DispositionClick is just a method I created, but you can do any number of things here.
                cdView.Click += (object sender, EventArgs e) => {
                        DispositionClick(cd, cdView);
                };
    
                    //Finally, we add it to the LinearLayout
                dispositionLayout.AddView (cdView);
        }
    

    I like the above method because it's scroll view friendly, and more intuitive to your average Android user. The other option is still viable, but I think this makes more sense, and it takes up exactly as much room as it needs for the list. One note here, there is no separator between list items, so you'd just have to create a programmatic view object that's 1dip high and matchParent width and add that to the LinearLayout between objects if you want them to have lines between them, but that should be easy to do.

    Please let me know if you have any questions about this method.

  • PeterMurphyPeterMurphy USMember ✭✭

    @RobCrossley‌ , this is working perfectly, thank you! However, I want to set the background colour of just the currently selected item in LinearLayout. I can set it, but of course previously selected items retain their background colour too. Is there a clever way to clear the colour on all other child views before setting the selected view's background colour?

                foreach (var item in items)
                {
                    //snip...
    
                    itemView.Click += (s, e) =>
                    {
                        //snip...
                        itemView.SetBackgroundColor(Color.Pink);
                    };
    
                    listContainer.AddView(itemView);
                }
    
                return listContainer;
    
  • FredyWengerFredyWenger CHInsider ✭✭✭✭✭

    @RobCrossley‌:

    Hy Rob
    I am developing with Xamarin.Forms and have a big problem after the latest Pre-updates to XF.
    In my app the users can search for various search-criteria's. I have searched and worked for weeks to find and implement a user-friendly way to select the search-criteria's on a single page.
    I have found a solution in the way that I "couple" a searchbar with a Listview and so "create" a (not existing) "Combox".
    My (various) ListViews are placed inside a ScrollView.
    This has worked fine on all platforms (iOS, Android and also WP) before the Pre-1 to XF came out.
    After Pre-1 the ListViews can't be scrolled anmore in Android while it further works without problems in iOS.
    I then have placed ad bug in bugzilla and ask for bugfixing directly (as this breaks my app on Android).
    I then have received the simple answer... don't use a Listview in an ScrollView.
    As I can't live with this answer (I see no other solution to meet my needs and this has worked before Pre-1) I desperately seek now for an solution...
    By my seeking, I have seen this thread and your solution...
    I like your solution as it seems to be "clean and small", but I don't know, how to implement it in Xamarin.Forms.
    As far as I understand your code-snipped, it's an "overwrite" of the (Andriod-)ListView-handler, that prevent the parant-container (ScrollView) to handle the scroll-events.
    What I don' understand (in your code) is, that the Parent.RequestDisallowInterceptTouchEvent is set to true by down, but to false by up.
    Is there a special reason for that?

    And... unfortunately... I don't know, how to implement your code in Forms.
    How to "In your activity, inherit View.IOnTouchListener" in a XF-Page and how to implement the android-specific-code?

    Can you help me further please...?

    I'm not the only XF-Developer, that have this problem now.
    If I am able to bring your solution to work in XF, I will paste the solution in the XF-forum, so that also other XF-Developers can benefit...

    Thanks a lot

    In your activity, inherit View.IOnTouchListener

    Then paste in this function:
    public bool OnTouch(View v, MotionEvent e)
    {
    switch (e.Action) {
    case MotionEventActions.Down:
    v.Parent.RequestDisallowInterceptTouchEvent (true);
    break;
    case MotionEventActions.Up:
    v.Parent.RequestDisallowInterceptTouchEvent (false);
    break;
    }

            v.OnTouchEvent (e);
            return true;
        }
    

    Finally, set your listview's On Touch listener to this. So if your ListView is named listView, for instance, then you'd add this line of code:

    listView.SetOnTouchListener (this);

  • AboooaasAboooaas USMember

    Hello All,
    I have developed a application with list view, i using adapter to fill list , but list view doesn't showing scroll bar.
    Below used code..

    private void SetListViewHeight(ListView _listView,BaseAdapter adp)
    {

            View item = adp.GetView (0, null, _listView);
                item.Measure (0, 0);
                ViewGroup.LayoutParams listViewParams = empListView.LayoutParameters;
            listViewParams.Height =(int)adp.Count * (int)(item.MeasuredHeightAndState+item.MeasuredHeightAndState*0.25);
                empListView.LayoutParameters = listViewParams;
                empListView.RequestLayout ();
    
        }
    
        msg = getEmployeesListCompletedEventArgs.Result.ToString();     
                TestWcfService.Employee[] emp= getEmployeesListCompletedEventArgs.Result;
                empList = (from c in emp
                    select c).ToList<Employee> ();
        empAdapter = new  EmployeeAdapter (this, empList);
                SetListViewHeight(empListView,empAdapter);
                empListView.Adapter = empAdapter;
    

    Can any one guide me if i am doing any thing wrong..

  • asmaivazehasmaivazeh USMember

    hi Rob Crossley
    i use your idea in my listview in monoandroid and it work well
    thanks for your idea :)

  • JonathanDibbleJonathanDibble GBMember ✭✭

    Thanks @RobCrossley that was a perfect solution for me.

  • SagarPanwalaSagarPanwala USMember ✭✭✭

    ListView inside ScrollView works well, but it created views multiple times, because in GetView methods we are passing null. So my screen sticks for 5 seconds whenever I have more view(it has always).

  • ashiishtashiisht INMember ✭✭

    @MattFara , Hi i trying to follow your approach in my code but i am unable to find "container" in my activity class in android xamarin.

    var cdView = adapter.GetView (contactDetails.IndexOf (cd), null, container);

    Please clear more about this.

    Thanks

  • MizanurRahman.0834MizanurRahman.0834 USMember ✭✭

    Use following code in this case

    yourListView.NestedScrollingEnabled=true;

    OR

    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;               
        }            
    }
    

    It will save your time

Sign In or Register to comment.