来自官方文档:
protected void onLayout (boolean changed, int left, int top, int right, int bottom)
Parameters
changed This is a new size or position for this view
left Left position, relative to parent
top Top position, relative to parent
right Right position, relative to parent
bottom Bottom position, relative to parent
为什么我的自定义视图会被changed=false
重复调用?这是正常的吗?
这是调用树:
Synoptic.onLayout(boolean, int, int, int, int) line: 130
Synoptic(View).layout(int, int, int, int) line: 11282
Synoptic(ViewGroup).layout(int, int, int, int) line: 4224
RelativeLayout.onLayout(boolean, int, int, int, int) line: 925
RelativeLayout(View).layout(int, int, int, int) line: 11282
RelativeLayout(ViewGroup).layout(int, int, int, int) line: 4224
LinearLayout.setChildFrame(View, int, int, int, int) line: 1628
LinearLayout.layoutHorizontal() line: 1617
LinearLayout.onLayout(boolean, int, int, int, int) line: 1401
LinearLayout(View).layout(int, int, int, int) line: 11282
LinearLayout(ViewGroup).layout(int, int, int, int) line: 4224
SwipeView(FrameLayout).onLayout(boolean, int, int, int, int) line: 431
SwipeView(HorizontalScrollView).onLayout(boolean, int, int, int, int) line: 1382
SwipeView.onLayout(boolean, int, int, int, int) line: 154
SwipeView(View).layout(int, int, int, int) line: 11282
SwipeView(ViewGroup).layout(int, int, int, int) line: 4224
LinearLayout.setChildFrame(View, int, int, int, int) line: 1628
LinearLayout.layoutVertical() line: 1486
LinearLayout.onLayout(boolean, int, int, int, int) line: 1399
LinearLayout(View).layout(int, int, int, int) line: 11282
LinearLayout(ViewGroup).layout(int, int, int, int) line: 4224
FrameLayout.onLayout(boolean, int, int, int, int) line: 431
FrameLayout(View).layout(int, int, int, int) line: 11282
FrameLayout(ViewGroup).layout(int, int, int, int) line: 4224
LinearLayout.setChildFrame(View, int, int, int, int) line: 1628
LinearLayout.layoutVertical() line: 1486
LinearLayout.onLayout(boolean, int, int, int, int) line: 1399
LinearLayout(View).layout(int, int, int, int) line: 11282
LinearLayout(ViewGroup).layout(int, int, int, int) line: 4224
PhoneWindow$DecorView(FrameLayout).onLayout(boolean, int, int, int, int) line: 431
PhoneWindow$DecorView(View).layout(int, int, int, int) line: 11282
PhoneWindow$DecorView(ViewGroup).layout(int, int, int, int) line: 4224
ViewRootImpl.performTraversals() line: 1514
ViewRootImpl.handleMessage(Message) line: 2467
ViewRootImpl(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 137
ActivityThread.main(String[]) line: 4424
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 511
ZygoteInit$MethodAndArgsCaller.run() line: 784
ZygoteInit.main(String[]) line: 551
NativeStart.main(String[]) line: not available [native method]
答案 0 :(得分:11)
文档中的关键部分是:
当此视图应为每个子视图指定大小和位置时,从布局调用。
如果ViewGroup中的View设置为wrap_content并且它的大小发生改变(例如TextView中的文本更改为更长的字符串),则会发生ViewGroup中的onLayout。这是因为视图在布局时会给出它们的大小,因此如果没有调用,View将永远不会被赋予新的大小。
答案 1 :(得分:7)
我发现了问题:对于像我这样的复合组件,其中包含TextView
,对.setText()
的重复调用会导致调用父onLayout()
...即使新文本等于当前TextView
文本!
所以我解决了:
public void setTextViewText(String text) {
if (!this.textViewValue.getText().equals(text)) {
this.textViewValue.setText(text);
}
}