【问题标题】:Custom layout, onMeasure/onLayout called continuously自定义布局,onMeasure/onLayout 连续调用
【发布时间】:2013-06-10 00:39:24
【问题描述】:

我编写了自己的布局(子类化一个 RelativeLayout)。我从调试器中看到 onMeasure() 和 onLayout() 被连续调用。这是正常行为吗?堆栈跟踪从 dispatchMessage() 开始:

Synoptic.onMeasure(int, int) line: 125  
Synoptic(View).measure(int, int) line: 12727    
RelativeLayout.measureChildHorizontal(View, RelativeLayout$LayoutParams, int, int) line: 594    
RelativeLayout.onMeasure(int, int) line: 376    
RelativeLayout(View).measure(int, int) line: 12727  
LinearLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 4698    
LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 
LinearLayout.measureHorizontal(int, int) line: 1017 
LinearLayout.onMeasure(int, int) line: 555  
LinearLayout(View).measure(int, int) line: 12727    
SwipeView(HorizontalScrollView).measureChildWithMargins(View, int, int, int, int) line: 1159    
SwipeView(FrameLayout).onMeasure(int, int) line: 293    
SwipeView(HorizontalScrollView).onMeasure(int, int) line: 303   
SwipeView(View).measure(int, int) line: 12727   
LinearLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 4698    
LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 
LinearLayout.measureVertical(int, int) line: 660    
LinearLayout.onMeasure(int, int) line: 553  
LinearLayout(View).measure(int, int) line: 12727    
LinearLayout.measureVertical(int, int) line: 812    
LinearLayout.onMeasure(int, int) line: 553  
LinearLayout(View).measure(int, int) line: 12727    
FrameLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 4698 
FrameLayout.onMeasure(int, int) line: 293   
FrameLayout(View).measure(int, int) line: 12727 
LinearLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 4698    
LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 
LinearLayout.measureVertical(int, int) line: 660    
LinearLayout.onMeasure(int, int) line: 553  
LinearLayout(View).measure(int, int) line: 12727    
PhoneWindow$DecorView(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 4698   
PhoneWindow$DecorView(FrameLayout).onMeasure(int, int) line: 293    
PhoneWindow$DecorView.onMeasure(int, int) line: 2092    
PhoneWindow$DecorView(View).measure(int, int) line: 12727   
ViewRootImpl.performTraversals() line: 1068 
ViewRootImpl.handleMessage(Message) line: 2446  
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]  

这里是 onLayout():

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

       if (changed) {

        itemGrid.getLayoutParams().width = (int) itemSize;
        itemGrid.getLayoutParams().height = (int) itemSize;

        itemProduction.getLayoutParams().width = (int) itemSize;
        itemProduction.getLayoutParams().height = (int) itemSize;

        itemConsumption.getLayoutParams().width = (int) itemSize;
        itemConsumption.getLayoutParams().height = (int) itemSize;

        imageViewFlowAnimation.getLayoutParams().height = (int) animationHeight;
        imageViewFlowAnimation.getLayoutParams().width = (int) animationWidth;
}   
    }

【问题讨论】:

  • 您能否发布您的onLayout() 和onMeasure() 方法的代码?
  • 好的,我添加了一些代码,itemGrid、itemProduction、itemConsumption 和 imageViewFlowAnimation 是 RelativeLayout 子项

标签: java android layout custom-controls android-relativelayout


【解决方案1】:

您不应该在任何一种方法中调用super。这就是陷入无限循环的原因。您还需要确保从onMeasure() 调用setMeasuredDimension();,否则会抛出异常。

【讨论】:

  • 如果我不在 onLayout() 中调用 super(),我在屏幕上什么也看不到。请注意,我通过调用 layoutInflater.inflate(R.layout.ui_synoptic, this, true); 加载布局 xml;在创作者身上。 xml 包含一个 RelativeLayout 本身
  • 然后尽量不要在onMeasure()中调用它,但一定要调用setMeasuredDimension()。
  • 我改变了:没有覆盖 onMeasure,只有一行 onLayout 用 child.layout() 调整子层。效果一样。
  • 也许问题出在孩子身上,迫使其父母重新计算布局?
【解决方案2】:

您是否尝试过: if (changed) super.onLayout(changed, l, t, r, b);

【讨论】:

  • 用于检查更改的参数。但我注意到只有当我忽略覆盖 onMeasure() 时循环才会中断。
  • 我解决了使用 if (changed) {>} 并将 super.onLayout() 放在 if 块之外。
猜你喜欢
  • 2013-07-25
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2015-02-01
  • 1970-01-01
  • 2023-03-15
  • 2012-08-29
相关资源
最近更新 更多