如何使 Linearlayout 可滚动,两个列表视图可滚动,包装其内容

How to make Linearlayout scrollable with two listviews scrollable which wrap their content

我知道这个问题已经被问过很多次了,但我仍然没有找到我真正喜欢的解决方案。有人可以建议最优雅的方式来做我想做的事情吗:

我有两个 Listview,我目前在一个 LinearLayout(垂直)中。我希望 Listviews 在涉及高度时包装它们的内容,这样它们就不需要在内部滚动。相反,我想在页面上向下滚动以查看溢出的内容。

在此先感谢您的帮助!如果您建议完全重新构建架构,那么我也对此持开放态度。我唯一要求的是尽可能干净和简单的解决方案。不喜欢骇人听闻的解决方法。 :)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" >
    </ListView>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" >
    </ListView>

</LinearLayout>

据我所知,您正试图将 ListView 设置为其内容所需的高度。

您可以创建一个扩展 ListView 的自定义列表视图并覆盖其 onMeasure 方法,如下所示:

public class UnscrollableListView extends ListView {

    public UnscrollableListView(Context context) {
        super(context);
    }

    public UnscrollableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public UnscrollableListView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int maxHeightSpec = MeasureSpec.makeMeasureSpec( 
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); 
        super.onMeasure(widthMeasureSpec, maxHeightSpec); 
    }

}

这将使您的列表视图包装其内容。

由于需要向下滚动,尝试添加一个ScrollView in your layout to wrap the LinearLayout。 最后,您的布局类似于:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <com.example.UnscrollableListView
            android:id="@+id/listview1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.example.UnscrollableListView
            android:id="@+id/listview2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</ScrollView>

是你想要的吗?

但我不得不说,这些代码使 listview 的性能就像具有许多相似子项的垂直线性布局一样。 它无法利用回收视图来提高布局性能,因为没有视图将被回收。

你可以看看这篇文章: Performance Tips for Android’s ListView

这样做,

listview_main.xml

    ?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:id="@+id/scrollview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >

                <LinearLayout
                    android:id="@+id/list_view1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" >
                </LinearLayout>

 <View
                android:layout_width="match_parent"
                android:layout_height="5dp"
                android:background="@android:color/black" />

                <LinearLayout
                    android:id="@+id/list_view2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" >
                </LinearLayout>
            </LinearLayout>
        </ScrollView>

</LinearLayout>

Adapter1.java(适配器 2 与适配器 1 相同)

public class Adapter1 extends BaseAdapter {

    private Activity activity;
    private LayoutInflater mInflater;
    private ArrayList<String> arraylist1 = new ArrayList<String>();

    public Adapter1(Activity act, ArrayList<String> array) {

        this.activity = act;
        this.arraylist1 = array;
        mInflater = LayoutInflater.from(activity);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return arraylist1.size();
    }

    @Override
    public Object getItem(int position) {
        return arraylist1.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return arraylist1.get(position).hashCode();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_item1, null);

            holder = new ViewHolder();

            holder.lablel = (TextView) convertView.findViewById(R.id.label);

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.lablel.setText(arraylist1.get(position).toString());

        return convertView;

    }

    private class ViewHolder {
        TextView lablel = null;
    }

}

MainActivity.java

public class MainActivity extends Activity {
    private ArrayList<String> arraylist1 = new ArrayList<String>();
    private ArrayList<String> arraylist2 = new ArrayList<String>();

    private Adapter1 adapter1 = null;
    private Adapter2 adapter2 = null;

    private LinearLayout listview2;
    private LinearLayout listview1;
    private ScrollView scrollView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_main);

        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");
        arraylist1.add("listview_item1");

        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");
        arraylist2.add("listview_item2");

        listview1 = (LinearLayout) findViewById(R.id.list_view1);
        listview2 = (LinearLayout) findViewById(R.id.list_view2);
        scrollView = (ScrollView) findViewById(R.id.scrollview);

        adapter1 = new Adapter1(MainActivity.this, arraylist1);
        adapter2 = new Adapter2(MainActivity.this, arraylist2);

        listview1.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub

                scrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });

        listview1.removeAllViews();
        if (adapter1 != null && adapter1.getCount() > 0) {
            for (int i = 0; i < adapter1.getCount(); i++) {

                final View convertView = adapter1.getView(i, null, null);
                if (listview1 != null)
                    listview1.addView(convertView);
            }
        }

        listview2.removeAllViews();
        if (adapter2 != null && adapter2.getCount() > 0) {
            for (int i = 0; i < adapter2.getCount(); i++) {

                final View convertView = adapter2.getView(i, null, null);
                if (listview2 != null)
                    listview2.addView(convertView);
            }
        }

    }

}