canScrollHorizontally()/canScrollVertically() 无法获取到正确执行的解决方案

最近遇到的一个问题一直困扰着我,执行以下代码无法获取正确的值。

boolean canScroll = view.canScrollHorizontally(1);

我的需求

使用一个 RecyclerView 实现了一个类似 Tab 效果,当这个 Tab 可以滑动时,显示最右侧的三角按钮,否则隐藏这个按钮。效果如图

首先想到的是 SDK 中自带的 View.canScrollHorizontally(intdirection) 接口,API 文档的解析为

Check if this view can be scrolled horizontally in a certain direction.

即如果这个 View 在指定的方向上是可以滑动的,那么就返回 true。参数 direction 为正数则向左滑动检测,负数则向右滑动检测。

API 的使用

一开始是直接调用

mCategoryReclycerView.setAdapter(mCategoryAdapter);
    if (mCategoryReclycerView.canScrollHorizontally(1)) {
        mCategoryBtn.setVisibility(View.VISIBLE);
    } else {
        mCategoryBtn.setVisibility(View.GONE);
    }

很明显这样的用法无法正确得到我想要的效果。原因是 RecyclerView 设置 Adapter 之后,数据还没有马上渲染,它内部数据是一个异步的操作。

于是我就想到 View.post(Runnable) 方法。

在 View.post()方法中执行

修改代码为,而且还延迟了100 ms。

mCategoryReclycerView.postDelayed(()->{          
        if (mCategoryReclycerView.canScrollHorizontally(1)) {
            mCategoryBtn.setVisibility(View.VISIBLE);
        } else {
            mCategoryBtn.setVisibility(View.GONE);
        }
    },100);

当 Tab 上的分类超过手机屏幕宽度之后,依然没有显示表示”更多”操作三角按钮。

这时候非常郁闷,程序员焦虑的心情可想而知。

正确的用法

各种找资料查 API 文档,踩坑和填坑之后,期间省略一万字,终于在 stackoverflow 上看一个回答,说可以放在 GloblaLayoutListener 中进行检测

于是修改代码为

mCategoryReclycerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            
            @Override
            public void onGlobalLayout() {                
                if (getActivity() == null || getActivity().isFinishing()) {                    
                    return;
                }                
                if (mCategoryReclycerView.canScrollHorizontally(1)) {
                    mCategoryBtn.setVisibility(View.VISIBLE);
                    //只要布局发生变动,这个方法执行多次,当拿到正确值,就把监听 remove 掉
                    mCategoryReclycerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                } else {
                    mCategoryBtn.setVisibility(View.GONE);
                }
            }
        });

执行代码,完美解决问题!

API 文档也是各种坑,文档中很多 API 都没有正确说明如何使用,这个需要开发者平时的积累。

原文发布于微信公众号 - 终身开发者(AngryCode)

原文发表时间:2019-06-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券