Android之getViewTreeObserver().addOnGlobalLayoutListener() 引起的页面滑动抖动解决

引言:问题是这样的,项目里有个功能需要在代码里面获取、计算控件宽度,因此项目里面引入了监听View绘制完成的方法。但是由于该方法的引入,导致页面滑动过程中,绑定了addOnGlobalLayoutListener()监听的控件存在滑动抖动现象。

  • Android中Activity的生命周期方法与 View的绘制流程方法的执行顺序为oncreate()→onResume()→onMeasure()→onLayout()→onWidnowFocusChanged()→.....→onDraw()...
    View.getWidth()/View.getWidth()都需要在onLayout()执行完后才有效,这就是为什么我们在onCreate(onLayout()方法前获取)View.getWidth()/View.getWidth()则为0的原因;

  • OnGlobalLayoutListener 是ViewTreeObserver的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver监听到,这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知。ViewTreeObserver不能直接实例化,而是通过getViewTreeObserver()获得。

  • 而我遇到的问题正好是在滑动屏幕的时,textview控件就上下抖动。问题其实很简单,滑动页面,textview可见到不可见,不可见到可见,View会被重绘,视图树的布局发生改变,此时OnGlobalLayoutListener会被一直监听,然后不断设置宽高,导致textview抖动现象。解决的办法就是计算出textview宽高后,应及时调用removeOnGlobalLayoutListener()方法清除OnGlobalLayoutListener。

//监听title 的view绘制完成后,获取宽度title.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
    public void onGlobalLayout() {
      LinearLayout.LayoutParams layoutParams = (LayoutParams)viewFlipper.getLayoutParams();

       layoutParams.width = AppUtils.getScreenWidth(getContext()) - (title.getWidth() + AppUtils.dip2px(getContext(), 100));

        viewFlipper.setLayoutParams(layoutParams);

        getViewTreeObserver().removeOnGlobalLayoutListener(this);

    }});
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容