前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >canScrollHorizontally()/canScrollVertically() 无法获取到正确执行的解决方案

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

作者头像
阳仔
发布2019-07-31 17:23:48
6K0
发布2019-07-31 17:23:48
举报
文章被收录于专栏:终身开发者终身开发者

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

代码语言:javascript
复制
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 的使用

一开始是直接调用

代码语言:javascript
复制
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。

代码语言:javascript
复制
mCategoryReclycerView.postDelayed(()->{          
        if (mCategoryReclycerView.canScrollHorizontally(1)) {
            mCategoryBtn.setVisibility(View.VISIBLE);
        } else {
            mCategoryBtn.setVisibility(View.GONE);
        }
    },100);

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

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

正确的用法

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

于是修改代码为

代码语言:javascript
复制
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 都没有正确说明如何使用,这个需要开发者平时的积累。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 终身开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 我的需求
  • API 的使用
  • 在 View.post()方法中执行
  • 正确的用法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档