我有一个班级
public class FancyView extends View implements View.OnTouchListener {
我需要获得视图的高度/宽度。
(它可能随着设备旋转而改变。当然,在初始化时也不知道高度/宽度。)
你可以这样做......
因此,实际上在课程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);
}
或者,你可以这样做......
再次在班级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);
}
});
}
(旁白:我猜init()
是最好的选择。)
两者似乎都运作良好。
(A)添加一个addOnLayoutChangeListener
的监听器和(B)覆盖onLayout(boolean changed
之间是否存在实际差异?
用例:在班级FancyView
内,我在图像上画了一些东西;所以我需要知道宽度/高度要绘制的大小。
脚注。我已经注意到在讨论问题的地方“Android,获取视图的宽度/高度”时,通常建议使用onWindowFocusChanged
9它“更容易”)。当onLayout(已更改)可用时,我真的不明白为什么你会这样做;也许我错过了什么。
答案 0 :(得分:4)
方法addOnLayoutChangeListener
是公共的,因此它允许添加外部更改侦听器。 OTOH onLayout
受到保护,因此仅供内部使用。
对于内部使用,我的理解是两种方法都提供相同的结果,但覆盖更清晰。
检查View的源代码我看到使用更改侦听器的方法是
public void layout(int l, int t, int r, int b)
此方法在内部调用onLayout
并更改侦听器,确认两个方法都是等效的,因为它们以相同的方式触发。如果在任何情况下它们不会同时被调用,则可能是由于控件实现上的错误引起的。