addOnLayoutChangeListener和onLayout之间的区别(已更改)?

Fat*_*tie 6 java android

我上课了

public class FancyView extends View implements View.OnTouchListener {
Run Code Online (Sandbox Code Playgroud)

我需要获得视图的高度/宽度.

(它可能会随着设备旋转而改变.当然,在初始化时也不知道高度/宽度.)

你可以这样做...

所以,实际上在类中FancyView只是覆盖onLayout(changed)

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    int hh = getHeight();
    Log.d("~", "Using onLayout(changed), height is known: " +hh);
}
Run Code Online (Sandbox Code Playgroud)

或者,你可以这样做......

再次在课堂内FancyView使用addOnLayoutChangeListener

private void init() {
    addOnLayoutChangeListener(new OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top,
                                   int right, int bottom, int oldLeft, int oldTop,
                                   int oldRight, int oldBottom) {
            Log.d("~", "Using addOnLayoutChangeListener, height is known: " +hh);
        }
    });

}
Run Code Online (Sandbox Code Playgroud)

(旁白:我想这init()是最好的地方.)

两者似乎运作良好.

(A)添加一个监听器addOnLayoutChangeListener和交替(B)覆盖之间是否有任何实际区别onLayout(boolean changed

用例:在课堂上FancyView我在图像上画一些东西; 所以我需要知道宽度/高度要绘制的大小.


脚注.我已经注意到问题在哪里讨论"Android,获取视图的宽度/高度",通常建议使用onWindowFocusChanged9as它"更容易").当onLayout(已更改)可用时,我真的不明白为什么你会这样做; 也许我错过了什么.

Cla*_*edi 5

方法addOnLayoutChangeListener是公共的,因此它允许添加外部更改侦听器。OTOHonLayout受到保护,因此仅供内部使用。

对于内部使用,我的理解是两种方法提供相同的结果,但覆盖更干净一些。

检查View的源代码我发现使用更改侦听器的方法是

public void layout(int l, int t, int r, int b)
Run Code Online (Sandbox Code Playgroud)

此方法在内部调用onLayout并更改侦听器,确认这两种方法是等效的,因为它们以相同的方式触发。如果存在不同时调用的情况,则可能是由于控件实现上的错误引起的。