为什么view.onLayout()被重复调用时更改= false?

从官方文档:

Android文档 – 查看

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] 

文档中的关键部分是:

当这个视图为每个孩子分配一个大小和位置时,从布局调用。

如果ViewGroup中的View被设置为wrap_content,并且它的大小发生了变化(例如,TextView中的文本变成了一个更长的string),那么ViewGroup中的onLayout就会出现。 这是因为视图在布局时被赋予了它们的大小,所以如果没有这个调用,视图将永远不会被赋予新的大小。

我发现这个问题:对于像我这样的复合组件,它包含一个TextView ,对onLayout()的重复调用会导致调用父对象的onLayout()

即使新文本等于当前的TextView文本!

所以我解决了:

 public void setTextViewText(String text) { if (!this.textViewValue.getText().equals(text)) { this.textViewValue.setText(text); } }