在FrameLayout中将两个列表视图同步在一起

时间:2015-06-11 20:30:38

标签: android listview android-listview

这是我当前的布局配置:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ListView
        android:id="@+id/list_1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:drawSelectorOnTop="false"
        android:dividerHeight="0dp"
        android:divider="@null"
        android:scrollbars="none" />

    <ListView
        android:id="@+id/list_2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:drawSelectorOnTop="false"
        android:dividerHeight="0dp"
        android:divider="@null"
        android:scrollbars="none" />

</FrameLayout>

顶部listview基本上是基本listview的滚动叠加:list_1,它们必须具有相同的高度。叠加在空闲时不可见,但拖动时有一些alpha,并显示list_1当前部分。

我这样做是为了让列表1和列表2具有相同的内容高度,但它们对于自己的列表项具有不同的布局。

知道这里的list_2会在这里捕获触摸事件,我想同步listview滚动偏移。我用这个例子部分管理了它:

mListView2.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {

                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    View c = mListViewMonths.getChildAt(0);
                    int scrolly = -c.getTop() + mListViewMonths.getFirstVisiblePosition() * c.getHeight();
                    mListViewWeeks.setScrollY(scrolly);
                }
            });

除了listview1滚动之外,但是当向下滚动时,不会绘制listview1的列表项。我在这里缺少什么?

或者更好,将触摸事件发送到listview,而不是所有那些滚动技术。想法?

2 个答案:

答案 0 :(得分:0)

这有点像黑客但应该有用。

<强> activity_main_activity_list.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.android.recyclerview.MainActivityList">

    <ScrollView
        android:id="@+id/scroll2"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

            <ListView
                android:id="@+id/list_2"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:cacheColorHint="@android:color/transparent"
                android:divider="@null"
                android:dividerHeight="0dp"
                android:drawSelectorOnTop="false"
                android:scrollbars="none"/>
        </LinearLayout>
    </ScrollView>


    <ScrollView
        android:id="@+id/scroll1"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

            <ListView
                android:id="@+id/list_1"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:cacheColorHint="@android:color/transparent"
                android:divider="@null"
                android:dividerHeight="0dp"
                android:drawSelectorOnTop="false"
                android:scrollbars="none"/>

        </LinearLayout>
    </ScrollView>
</RelativeLayout>

<强> MainActivityList

public class MainActivityList extends Activity {

    ScrollView scroll1, scroll2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_activity_list);

        ListView list_1 = (ListView) findViewById(R.id.list_1);
        // Set list_1 Adapter
        SetListOneHeight.setListViewHeight(list_1);

        ListView list_2 = (ListView) findViewById(R.id.list_2);
        // Set list_2 Adapter
        SetListTwoHeight.setListViewHeight(list_2);

        scroll1 = (ScrollView) findViewById(R.id.scroll1);
        scroll2 = (ScrollView) findViewById(R.id.scroll2);

        scroll1.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                int scrollY = scroll1.getScrollY();
                scroll2.scrollTo(0, scrollY);
            }
        });
    }
}

创建两个单独的Java类

<强> SetListOneHeight

public class SetListOneHeight {
    public static void setListViewHeight(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);
        listView.requestLayout();
    }
}

<强> SetListTwoHeight

public class SetListTwoHeight {
    public static void setListViewHeight(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);
        listView.requestLayout();
    }
}

答案 1 :(得分:0)

我终于通过在这里使用这个助手类来实现这个目的:

Helper class for calculating relative scroll offsets in a ListView

然后在list2中,滚动侦听器只需执行:

@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    int incrementalOffset = mScrollTracker.calculateIncrementalOffset(firstVisibleItem, visibleItemCount);
    mListView2.scrollListBy(-incrementalOffset);
}

那就是它!