2014-02-18 20 views

回答

2

这是因为当渲染View时,包含ViewViewGroup在映射出每个视图在屏幕上出现的位置时会经过某些步骤。一个ViewGroup采取的步骤是:

  1. 措施(在ViewGroup措施,其所有子视图)
  2. 布局
  3. (在的ViewGroup在它们在屏幕上的位置,根据他们的测量结果和 ViewGroup.LayoutParams定位测量子女)
  4. 绘图(视图绘制在屏幕上)。

由于拉延步骤是最后一步在屏幕上呈现View■当,在该过程的这个步骤中添加额外View小号可能改变(无效)中的整个布局。如果你看看源代码ViewGroup你会看到,在打电话给addView(View v)再次开始整个布局的过程:

public void addView(View child, int index, LayoutParams params) { 
    if (DBG) { 
     System.out.println(this + " addView"); 
    } 

    // addViewInner() will call child.requestLayout() when setting the new LayoutParams 
    // therefore, we call requestLayout() on ourselves before, so that the child's request 
    // will be blocked at our level 
    requestLayout(); 
    invalidate(true); 
    addViewInner(child, index, params, false); 
} 

此外,当ViewGroup绘制其子View S上的屏幕上,它通常遍历当前添加到ViewGroup的所有View。因此,如果这种类型的事件是在绘制方法期间调度的,那么它可能会导致ViewGroup尝试绘制尚未完成呈现的必要步骤的View

至于相关的方法,这些方法本质上会使ViewGroup的当前绘图操作无效。

编辑:

的SurfaceHolder.Callback方法跟踪你的绘图表面或SurfaceView/GLSurfaceView的状态只是Interface方法。由于布局的状态应该保持不变,直到Draw步骤完成,所以在这个过程中不应该真的需要调用这个方法。但是,由于这些方法基本上都是您实现的接口方法(它们在源代码中默认为空),因此调用其中一种方法应该会导致错误,尽管我不确定它们应该没有真正的原因这样做是适当的。一种情况下,如果你的底层实现导致像我上面解释的问题,将会遇到问题...

+0

感谢您的回答!关于surfaceChanged部分,你有什么要说的吗? – kolistivra

+0

- 查看我的编辑。 – Submersed