解决StaggeredGridView加载更多滑到顶部的问题

本文介绍了在使用StaggeredGridView并结合Android-PullToRefresh实现下拉刷新和上拉加载更多功能时遇到的一个问题:每次加载更多后,瀑布流会滚动到顶部。解决方案包括修改StaggeredGridView的源代码或在调用notifyDataSetChanged时进行处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做瀑布流一般比较好的开源项目有:

StaggeredGridViewAndroidStaggeredGridPinterestLikeAdapterView

其中PinterestLikeAdapterView和AndroidStaggeredGrid 都是继承自AbsListView,而StaggeredGridView是直接集成ViewGroup得来的。

在项目中我使用了StaggeredGridView,后来加入Android-PullToRefresh来实现下拉刷新,上拉加载更多,但是发现每次加载更多调用adapter.notifyDataSetChanged()后,瀑布流都跑到position = 0的位置,视图没能在当期位置下。

好了不罗嗦了,下面说下两种解决方式,一种是改变源代码,另一种则是在每次调用notifyDataSetChanged时处理。

(1、)改变源代码,我们找到AdapterDataSetObserver这个地方,大约在2030行左右。

其中代码是

private class AdapterDataSetObserver extends DataSetObserver {
        @Override
        public void onChanged() {
            mDataChanged = true;
            mItemCount = mAdapter.getCount();

            // TODO: Consider matching these back up if we have stable IDs.
            mRecycler.clearTransientViews();

            if (!mHasStableIds) {
                // Clear all layout records and recycle the views
                mLayoutRecords.clear();
                recycleAllViews();

                // Reset item bottoms to be equal to item tops
                final int colCount = mColCount;
                for (int i = 0; i < colCount; i++) {
                    mItemBottoms[i] = mItemTops[i];
                }
            }

            // reset list if position does not exist or id for position has changed
            if(mFirstPosition > mItemCount-1 || mAdapter.getItemId(mFirstPosition) != mFirstAdapterId){
            	mFirstPosition = 0;
            	Arrays.fill(mItemTops, 0);
            	Arrays.fill(mItemBottoms, 0);

            	if(mRestoreOffsets!=null)
            	Arrays.fill(mRestoreOffsets, 0);
            }

            // TODO: consider repopulating in a deferred runnable instead
            // (so that successive changes may still be batched)
            requestLayout();
        }

        @Override
        public void onInvalidated() {
        }
    }
我们做的是把下面这些代码屏蔽掉就可以了

// reset list if position does not exist or id for position has changed
            if(mFirstPosition > mItemCount-1 || mAdapter.getItemId(mFirstPosition) != mFirstAdapterId){
            	mFirstPosition = 0;
            	Arrays.fill(mItemTops, 0);
            	Arrays.fill(mItemBottoms, 0);

            	if(mRestoreOffsets!=null)
            	Arrays.fill(mRestoreOffsets, 0);
            }
(2、)是在每次调用 notifyDataSetChanged做处理,

代码如下:

private Parcelable state;

//		state = staggeredGridView.onSaveInstanceState();
		
		adapter.notifyDataSetChanged();
		pullToRefreshStaggeredGrid.onRefreshComplete();
//		staggeredGridView.onRestoreInstanceState(state);

以上是解决方式,大家如果有更好的可以回复我!


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值