如何保存使用CursorAdapter的ListView的滚动位置?

时间:2015-10-20 16:52:47

标签: android listview

我的ListView(StickyListHeadersListView)不保存确切的滚动位置。我引用了这个:

Maintain/Save/Restore scroll position when returning to a ListView

当用户点击列表中的项目时,我会在应用程序转换为活动之前使用SharedPreferences保存“index”和“top”。当我按下活动以返回带有ListView的片段时,列表从它离开时到达第一个可见列表项的顶部,但不是确切的位置(即,如果第一个可见项目被中途切断,它应该在返回片段时中途切断。)

换句话说,偏移量没有保存。就像我说的,它可以保存第一个可见位置,但确切的滚动没有被保存。

    mAdapter = new PeopleAdapter(getActivity(), null);
    mList = (StickyListHeadersListView) rootView.findViewById(R.id.stickyList);
    mList.setAdapter(mAdapter);
    mList.setAreHeadersSticky(true);
    mList.setDividerHeight(0);
    mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Cursor cursor = mAdapter.getCursor();
            if (cursor != null && cursor.moveToPosition(position)) {
                MainActivity.setIndex(mList.getFirstVisiblePosition());
                View v = mList.getListChildAt(0);
                int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());
                MainActivity.setTop(top);
                Intent intent = new Intent(getActivity(), ContactDetailActivity.class);
                startActivity(intent);
        }
    });

光标加载完毕后,我正在调用

    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        android.util.Log.i(TAG, "Cursor loaded. (" + data.getCount() + " rows)");
        mList.setSelectionFromTop(MainActivity.getIndex(), MainActivity.getTop());
        mAdapter.changeCursor(data);
        mAdapter.notifyDataSetChanged();
}

1 个答案:

答案 0 :(得分:0)

可以使用savedInstanceState来保存ListView的精确滚动,但是在很多情况下它会随着活动一起被破坏,我们不能轻易地保存savedInstanceState,因为我们只能将它真正转换为Parcelable对象,不是为了坚持而设计的。即使在尝试从ListView获取savedInstanceState时,我们也遇到了一些问题。 null通常会返回给我们,因为Android文档指定在“没有什么有趣的东西可以保存”时发生。好吧,在这种情况下,滚动非常有趣!可悲的是,Android并不总是会给我们这个,这带来了很多问题......

事实上,我对此进行了更多研究,并注意到Android文档说“此状态应该只包含非持久性信息或以后无法重建的信息。例如,您永远不会将当前位置存储在屏幕上,因为当视图的新实例放置在其视图层次结构中时,将再次计算。“,所以这不是可行的方法。

当然,我们仍然可以使用您正在使用的方法,但它绝不会在所有设备上使用。对于一般应用程序,我建议只保留列表项的索引并在顶部启动用户。

除了从ListView本身获取详细信息之外,我不相信我们可以使用任何其他方法来访问滚动位置。因此,我们只能使用我们提供的东西。

你可能是超级疯狂的想法,并尝试将ListView放在ScrollView中(或者其他一些容器也可以使用),然后我们可以使用getScrollY()和setScrollY()之类的方法,但这依赖于总是存在相同数量的列表项和所有列表项保持相同的大小。