引言:問題是這樣的,項目里有個功能需要在代碼里面獲取、計算控件寬度,因此項目里面引入了監(jiān)聽View繪制完成的方法。但是由于該方法的引入,導致頁面滑動過程中,綁定了addOnGlobalLayoutListener()監(jiān)聽的控件存在滑動抖動現(xiàn)象。
Android中Activity的生命周期方法與 View的繪制流程方法的執(zhí)行順序為oncreate()→onResume()→onMeasure()→onLayout()→onWidnowFocusChanged()→.....→onDraw()...
View.getWidth()/View.getWidth()都需要在onLayout()執(zhí)行完后才有效,這就是為什么我們在onCreate(onLayout()方法前獲取)View.getWidth()/View.getWidth()則為0的原因;OnGlobalLayoutListener 是ViewTreeObserver的內(nèi)部類,當一個視圖樹的布局發(fā)生改變時,可以被ViewTreeObserver監(jiān)聽到,這是一個注冊監(jiān)聽視圖樹的觀察者(observer),在視圖樹的全局事件改變時得到通知。ViewTreeObserver不能直接實例化,而是通過getViewTreeObserver()獲得。
而我遇到的問題正好是在滑動屏幕的時,textview控件就上下抖動。問題其實很簡單,滑動頁面,textview可見到不可見,不可見到可見,View會被重繪,視圖樹的布局發(fā)生改變,此時OnGlobalLayoutListener會被一直監(jiān)聽,然后不斷設(shè)置寬高,導致textview抖動現(xiàn)象。解決的辦法就是計算出textview寬高后,應及時調(diào)用removeOnGlobalLayoutListener()方法清除OnGlobalLayoutListener。
//監(jiān)聽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);
}});