AndroidViewTreeObserver.OnGlobalLayoutListener烦恼

Android ViewTreeObserver.OnGlobalLayoutListener troubles

我在 onCreate() 方法中使用 ViewTreeObserver.OnGlobalLayoutListener 来获取布局的宽度。它工作得很好,但是当我在 onGlobalLayout() 中使用变量进行操作时,回调更改不会保留在它之外。

例如,当我在 Activity 的字段中保存布局的宽度时,它 returns 前一个值或默认值(在我的例子中为 0)在 onGlobalLayout() 方法之外.当我更改变量的引用时,它们在方法之外将为空。

layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
    width = layout.getWidth(); // width - activity's field
    Log.d("myLogs", width); //return rigth value
}
});
Log.d("myLogs", width); //return 0

我不知道如何处理它,也许我需要通过其他方式获得 Layout 的宽度。

提前致谢)

您将 OnGlobalLayoutListener 传递给 ViewTreeObserver,仅此而已,方法 onGlobalLayout 不会立即调用,它将在该布局发生布局事件时调用。因此,方法 addOnGlobalLayoutListener 立即并且您收到未更改的 width 变量值。

@busylee 说的对。

那么如果你想在 ViewTreeObserver 之外访问这个值,解决方案是这样的:

private int width;

layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int w = layout.getWidth(); // width - activity's field
        Log.d("myLogs", w); //return rigth value
        setWidth(w);
    }
});

private void setWidth(int w) {
    this.width = w;  //get rigth value
    Log.d("myLogs", width);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_account);

    topOfScreen = findViewById(R.id.spc_account_top);
    icon = findViewById(R.id.img_account_icon);

    //[...]


    getPosition();
}

void getPosition(){
    topOfScreen.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int[] pos = new int[2];
            topOfScreen.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            topOfScreen.getLocationOnScreen(pos);
            setAnimation(-1*pos[0]);
            Log.d("X and Y Point", pos[0] + " "+ pos[1]);
        }
    });
}

public void setAnimation(int y) {
    icon.animate().translationYBy(y).setDuration(1500);
    screen.animate().setDuration(2000).alpha(1);
}