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

后端 未结 27 3222
轮回少年
轮回少年 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:44

    Before it was not possible. But with the release of new Appcompat libraries and Design libraries, this can be achieved.

    You just have to use NestedScrollView https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html

    I am not aware it will work with Listview or not but works with RecyclerView.

    Code Snippet:

    <android.support.v4.widget.NestedScrollView 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    </android.support.v4.widget.NestedScrollView>
    
    0 讨论(0)
  • 2020-11-21 05:46

    Using a ListView to make it not scroll is extremely expensive and goes against the whole purpose of ListView. You should NOT do this. Just use a LinearLayout instead.

    0 讨论(0)
  • 2020-11-21 05:46

    hey I had a similar issue. I wanted to display a list view that didn't scroll and I found that manipulating the parameters worked but was inefficient and would behave differently on different devices.. as a result, this is a piece of my schedule code which actually does this very efficiently.

    db = new dbhelper(this);
    
     cursor = db.dbCursor();
    int count = cursor.getCount();
    if (count > 0)
    {    
    LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layoutId);
    startManagingCursor(YOUR_CURSOR);
    
    YOUR_ADAPTER(**or SimpleCursorAdapter **) adapter = new YOUR_ADAPTER(this,
        R.layout.itemLayout, cursor, arrayOrWhatever, R.id.textViewId,
        this.getApplication());
    
    int i;
    for (i = 0; i < count; i++){
      View listItem = adapter.getView(i,null,null);
      linearLayout.addView(listItem);
       }
    }
    

    Note: if you use this, notifyDataSetChanged(); will not work as intended as the views will not be redrawn. Do this if you need a work around

    adapter.registerDataSetObserver(new DataSetObserver() {
    
                @Override
                public void onChanged() {
                    super.onChanged();
                    removeAndRedrawViews();
    
                }
    
            });
    
    0 讨论(0)
  • 2020-11-21 05:46

    There are two issue when using a ListView inside a ScrollView.

    1- ListView must fully expand to its children height. this ListView resolve this:

    public class ListViewExpanded extends ListView
    {
        public ListViewExpanded(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            setDividerHeight(0);
        }
    
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST));
        }
    }
    

    Divider height must be 0, use padding in rows instead.

    2- The ListView consumes touch events so ScrollView can't be scrolled as usual. This ScrollView resolve this issue:

    public class ScrollViewInterceptor extends ScrollView
    {
        float startY;
    
        public ScrollViewInterceptor(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent e)
        {
            onTouchEvent(e);
            if (e.getAction() == MotionEvent.ACTION_DOWN) startY = e.getY();
            return (e.getAction() == MotionEvent.ACTION_MOVE) && (Math.abs(startY - e.getY()) > 50);
        }
    }
    

    This is the best way I found to do the trick!

    0 讨论(0)
  • 2020-11-21 05:46

    Here is my version of the code that calculates total height of the list view. This one works for me:

       public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null || listAdapter.getCount() < 2) {
            // pre-condition
            return;
        }
    
        int totalHeight = 0;
        int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(BCTDApp.getDisplaySize().width, View.MeasureSpec.AT_MOST);
        int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            if (listItem instanceof ViewGroup) listItem.setLayoutParams(lp);
            listItem.measure(widthMeasureSpec, heightMeasureSpec);
            totalHeight += listItem.getMeasuredHeight();
        }
    
        totalHeight += listView.getPaddingTop() + listView.getPaddingBottom();
        totalHeight += (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight;
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
    
    0 讨论(0)
  • 2020-11-21 05:47

    We could not use two scrolling simulteniuosly.We will have get total length of ListView and expand listview with the total height .Then we can add ListView in ScrollView directly or using LinearLayout because ScrollView have directly one child . copy setListViewHeightBasedOnChildren(lv) method in your code and expand listview then you can use listview inside scrollview. \layout xml file

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
     <ScrollView
    
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
             android:background="#1D1D1D"
            android:orientation="vertical"
            android:scrollbars="none" >
    
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="#1D1D1D"
                android:orientation="vertical" >
    
                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="40dip"
                    android:background="#333"
                    android:gravity="center_vertical"
                    android:paddingLeft="8dip"
                    android:text="First ListView"
                    android:textColor="#C7C7C7"
                    android:textSize="20sp" />
    
                <ListView
                    android:id="@+id/first_listview"
                    android:layout_width="260dp"
                    android:layout_height="wrap_content"
                    android:divider="#00000000"
                   android:listSelector="#ff0000"
                    android:scrollbars="none" />
    
                   <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="40dip"
                    android:background="#333"
                    android:gravity="center_vertical"
                    android:paddingLeft="8dip"
                    android:text="Second ListView"
                    android:textColor="#C7C7C7"
                    android:textSize="20sp" />
    
                <ListView
                    android:id="@+id/secondList"
                    android:layout_width="260dp"
                    android:layout_height="wrap_content"
                    android:divider="#00000000"
                    android:listSelector="#ffcc00"
                    android:scrollbars="none" />
      </LinearLayout>
      </ScrollView>
    
       </LinearLayout>
    

    onCreate method in Activity class:

     import java.util.ArrayList;
      import android.app.Activity;
     import android.os.Bundle;
     import android.view.Menu;
     import android.view.View;
     import android.view.ViewGroup;
     import android.widget.ArrayAdapter;
     import android.widget.ListAdapter;
      import android.widget.ListView;
    
       public class MainActivity extends Activity {
    
       @Override
       protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_inside_scrollview);
        ListView list_first=(ListView) findViewById(R.id.first_listview);
        ListView list_second=(ListView) findViewById(R.id.secondList);
        ArrayList<String> list=new ArrayList<String>();
        for(int x=0;x<30;x++)
        {
            list.add("Item "+x);
        }
    
           ArrayAdapter<String> adapter=new ArrayAdapter<String>(getApplicationContext(), 
              android.R.layout.simple_list_item_1,list);               
          list_first.setAdapter(adapter);
    
         setListViewHeightBasedOnChildren(list_first);
    
          list_second.setAdapter(adapter);
    
        setListViewHeightBasedOnChildren(list_second);
       }
    
    
    
       public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }
    
        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }
    
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
          }
    
    0 讨论(0)
提交回复
热议问题