How can I put a ListView into a ScrollView without it collapsing?

后端 未结 27 3224
轮回少年
轮回少年 2020-11-21 05:24

I\'ve searched around for solutions to this problem, and the only answer I can find seems to be \"don\'t put a ListView into a ScrollView\". I have yet to see any real expl

相关标签:
27条回答
  • 2020-11-21 05:59

    Here is small modification on @djunod's answer that I need to make it work perfectly:

    public static void setListViewHeightBasedOnChildren(ListView listView)
    {
        ListAdapter listAdapter = listView.getAdapter();
        if(listAdapter == null) return;
        if(listAdapter.getCount() <= 1) return;
    
        int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
        int totalHeight = 0;
        View view = null;
        for(int i = 0; i < listAdapter.getCount(); i++)
        {
            view = listAdapter.getView(i, view, listView);
            view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
    
    0 讨论(0)
  • 2020-11-21 06:00

    I converted @DougW's Utility into C# (used in Xamarin). The following works fine for fixed-height items in the list, and is going to be mostly fine, or at least a good start, if only some of the items are a bit bigger than the standard item.

    // You will need to put this Utility class into a code file including various
    // libraries, I found that I needed at least System, Linq, Android.Views and 
    // Android.Widget.
    using System;
    using System.Linq;
    using Android.Views;
    using Android.Widget;
    
    namespace UtilityNamespace  // whatever you like, obviously!
    {
        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));
            }
        }
    }
    

    Thanks @DougW, this got me out of a tight spot when I had to work with OtherPeople'sCode. :-)

    0 讨论(0)
  • 2020-11-21 06:01

    thanks to Vinay's code here is my code for when you can't have a listview inside a scrollview yet you need something like that

    LayoutInflater li = LayoutInflater.from(this);
    
                    RelativeLayout parent = (RelativeLayout) this.findViewById(R.id.relativeLayoutCliente);
    
                    int recent = 0;
    
                    for(Contatto contatto : contatti)
                    {
                        View inflated_layout = li.inflate(R.layout.header_listview_contatti, layout, false);
    
    
                        inflated_layout.setId(contatto.getId());
                        ((TextView)inflated_layout.findViewById(R.id.textViewDescrizione)).setText(contatto.getDescrizione());
                        ((TextView)inflated_layout.findViewById(R.id.textViewIndirizzo)).setText(contatto.getIndirizzo());
                        ((TextView)inflated_layout.findViewById(R.id.textViewTelefono)).setText(contatto.getTelefono());
                        ((TextView)inflated_layout.findViewById(R.id.textViewMobile)).setText(contatto.getMobile());
                        ((TextView)inflated_layout.findViewById(R.id.textViewFax)).setText(contatto.getFax());
                        ((TextView)inflated_layout.findViewById(R.id.textViewEmail)).setText(contatto.getEmail());
    
    
    
                        RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    
                        if (recent == 0)
                        {
                            relativeParams.addRule(RelativeLayout.BELOW, R.id.headerListViewContatti);
                        }
                        else
                        {
                            relativeParams.addRule(RelativeLayout.BELOW, recent);
                        }
                        recent = inflated_layout.getId();
    
                        inflated_layout.setLayoutParams(relativeParams);
                        //inflated_layout.setLayoutParams( new RelativeLayout.LayoutParams(source));
    
                        parent.addView(inflated_layout);
                    }
    

    the relativeLayout stays inside a ScrollView so it all becomes scrollable :)

    0 讨论(0)
  • 2020-11-21 06:02

    Insted of putting ListView inside a ScrollView , we can use ListView as a ScrollView. Things which has to be in ListView can be put inside the ListView. Other layouts on top and bottom of ListView can be put by adding layouts to header and footer of ListView. So the entire ListView will give you an experience of scrolling .

    0 讨论(0)
  • 2020-11-21 06:02

    You Create Custom ListView Which is non Scrollable

    public class NonScrollListView extends ListView {
    
        public NonScrollListView(Context context) {
            super(context);
        }
        public NonScrollListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                        Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
                super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
                ViewGroup.LayoutParams params = getLayoutParams();
                params.height = getMeasuredHeight();    
        }
    }
    

    In Your Layout Resources File

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    
        <!-- com.Example Changed with your Package name -->
    
        <com.Example.NonScrollListView
            android:id="@+id/lv_nonscroll_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </com.Example.NonScrollListView>
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/lv_nonscroll_list" >
    
            <!-- Your another layout in scroll view -->
    
        </RelativeLayout>
    </RelativeLayout>
    

    In Java File

    Create a object of your customListview instead of ListView like : NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);

    0 讨论(0)
  • 2020-11-21 06:02

    try this, this works for me, I forgot where I found it, somewhere in stack overflow, i'm not here to explained it why it doesn't work, but this is the answer :).

        final ListView AturIsiPulsaDataIsiPulsa = (ListView) findViewById(R.id.listAturIsiPulsaDataIsiPulsa);
        AturIsiPulsaDataIsiPulsa.setOnTouchListener(new ListView.OnTouchListener() 
        {
            @Override
            public boolean onTouch(View v, MotionEvent event) 
            {
                int action = event.getAction();
                switch (action) 
                {
                    case MotionEvent.ACTION_DOWN:
                    // Disallow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    break;
    
                    case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
                }
    
                // Handle ListView touch events.
                v.onTouchEvent(event);
                return true;
            }
        });
        AturIsiPulsaDataIsiPulsa.setClickable(true);
        AturIsiPulsaDataIsiPulsa.setAdapter(AturIsiPulsaDataIsiPulsaAdapter);
    

    EDIT !, I finally found out where I got the code. here ! : ListView inside ScrollView is not scrolling on Android

    0 讨论(0)
提交回复
热议问题