scwang90 / SmartRefreshLayout

🔥下拉刷新、上拉加载、二级刷新、淘宝二楼、RefreshLayout、OverScroll,Android智能下拉刷新框架,支持越界回弹、越界拖动,具有极强的扩展性,集成了几十种炫酷的Header和 Footer。
https://segmentfault.com/a/1190000010066071
Apache License 2.0
24.94k stars 4.96k forks source link

使用smartRefreshLayout上拉加载后footer高度问题 #1210

Closed 1336238592 closed 4 years ago

1336238592 commented 4 years ago

在调用finishLoadmore()之后,footer 只是view消失了,但是高度没有消失,页面没有回滚,需要手动往下拖一下,footer那段高度才会消失

经过测试发现recyclerview没满一屏的时候是可以回滚的,满了一屏就不会了。

主要我使用的场景是单个item会撑满全屏,就是类似抖音滑动切换屏幕,如果不回滚就会导致头部有一截高度会被推上去,刚好就是footer的高度,这个体验不太好。希望能提供一个方法,来设置是否需要回滚

1336238592 commented 4 years ago

大致找到原因了,在RefreshContentWrapper类中的scrollContentWhenFinished方法中 mScrollableView.canScrollVertically(1)这个判断逻辑有问题,当recyclerView没有满一屏的时候返回的都是false,只有当RecyclerView超过一屏的时候,滑动到底部的时候才是true,这个逻辑影响了分支判断,建议作者在这里换个判断方式,这样的判断会有问题。

1336238592 commented 4 years ago

经过进一步排查,发现一个问题,就是调用finishLoadMore()的时候和Adapter调用notifyDataSetChanged时存在时差问题,我发现调用finishLoadMore()的时候逻辑走到mScrollableView.canScrollVertically(1)发现mScrollableView.mAdapter中的数据已经被set好了,也就是说我先调用的finishLoadMore()后调用的adapter.setData()反而finishLoadMore()中的数据先被改了,这就引起了 mScrollableView.canScrollVertically(1)前后状态不一致。

究其原因个还是因为finishLoadMore()方法里面使用了mHandler.postDelayed(this, more);这个方法,大家都知道,postDelayed是不阻塞线程的,相当于多线程的效果,希望作者可以修一下这个地方。

目前的解决方案是添加一个延时,在调用finishLoadMore()900毫秒之后再调用数据更新方法adapter.setData()。这样就可以实现滚动收起footer了。

这里贴一部分代码,大家可以借鉴一下

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.xxx); mRefreshLayout = findViewById(R.id.refresh_layout); mRecycler = findViewById(R.id.vertical_recycler); new PagerSnapHelper().attachToRecyclerView(mRecycler); mRecycler.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new VerticalRecyclerViewAdapter(this); mRecycler.setAdapter(mAdapter); mAdapter.setData(getData(0)); mRefreshLayout.setEnableRefresh(false); mRefreshLayout.setEnableLoadMore(true); mRefreshLayout.setEnableClipFooterWhenFixedBehind(false); mRefreshLayout.setRefreshFooter(new ClassicsFooter(this)); mRefreshLayout.setEnableAutoLoadMore(false); mRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { @Override public void onLoadMore(@NonNull RefreshLayout refreshLayout) { mRefreshLayout.finishLoadMore(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(900); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendEmptyMessage(1); } }).start(); } }); }

Handler handler=new Handler(){
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg);
        mAdapter.setData(getData(mAdapter.getData().size()));
    }
};

public List<String> getData(int index) {
    List<String> list = new ArrayList<>();
    for (int i = index; i < 2 + index; i++) {
        list.add(i + "");
    }
    return list;
}
rivenlee0 commented 4 years ago

在调用finishLoadmore()之后,页脚只是查看消失了,但是高度没有消失,页面没有回滚,需要手动往下拖一下,footer那段高度才会消失

经过测试发现recyclerview没满一屏的时候是可以回滚的,满了一屏就不会了。

主要我使用的场景是临时会会满满全屏,就是类似抖音滑动切换屏幕,如果不回滚就会导致导致某个截距高度会被推上去,刚好就是footer的高度,这个体验不太好。希望能提供一个方法,来设置是否需要回滚

smartrefreshlayout设置setEnableNestedScroll(true)试试呢, 我这边也是布局复杂,出现footer(没有数据了)无法回弹的情况。设置这个属性后就好了,但偶尔也会卡一下。你可以试一试这样设置。 期待你尝试后的后续回复。

scwang90 commented 4 years ago

调用的先后顺序必须保证先更新数据,后关闭加载,具体做法参考 smart 的 demo

adapter.setData();//先更新数据
finishLoadMore();//后关闭Footer
SmilingBoy commented 3 years ago

然而这样并不能解决类似抖音这样的布局情况