12

我创建了一个扩展 ViewGroup 的自定义布局。一切正常,我得到了预期的布局。

我想动态更改布局中的元素。然而,这不起作用,因为我在 onCreate 中调用它,直到那时整个布局实际上并没有(绘制)到屏幕上,因此没有实际大小。

是否有任何事件可用于找出布局的膨胀何时完成?我尝试了 onFinishInflate 但这不起作用,因为 Viewgroup 有多个视图,并且会被多次调用。

我正在考虑在自定义布局类中创建一个界面,但不确定何时触发它?

4

2 回答 2

29

如果我正确理解您的要求,OnGlobalLayoutListener 可能会为您提供所需的内容。

  View myView=findViewById(R.id.myView);
  myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //At this point the layout is complete and the 
                //dimensions of myView and any child views are known.
            }
        });
于 2011-09-22T16:04:07.363 回答
2

通常在创建扩展Viewor的自定义布局时ViewGroup,您必须覆盖protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)and protected void onLayout(boolean changed, int left, int top, int right, int bottom)。这些在膨胀过程中被调用以获得与视图相关的大小和位置信息。此外,随后,如果您正在扩展,ViewGroup您将调用measure(int widthMeasureSpec, int heightMeasureSpec)其中layout(int l, int t, int r, int b)包含的每个子视图。(在 onMeasure() 中调用 measure(),在 onLayout() 中调用 layout())。

无论如何,在 中onMeasure(),你通常会做这样的事情。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
   // Gather this view's specs that were passed to it
   int widthMode = MeasureSpec.getMode(widthMeasureSpec);
   int widthSize = MeasureSpec.getSize(widthMeasureSpec);
   int heightMode = MeasureSpec.getMode(heightMeasureSpec);
   int heightSize = MeasureSpec.getSize(heightMeasureSpec);

   int chosenWidth = DEFAULT_WIDTH;
   int chosenHeight = DEFAULT_HEIGHT;
   if(widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY)
      chosenWidth = widthSize;
   if(heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.EXACTLY)
      chosenHeight = heightSize;

   setMeasuredDimension(chosenWidth, chosenHeight);

   *** NOW YOU KNOW THE DIMENSIONS OF THE LAYOUT ***
}

onLayout()您获得视图的实际像素坐标时,您可以像这样获得物理尺寸:

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
   // Android coordinate system starts from the top-left
   int width = right - left;
   int height = bottom - top;
}
于 2011-09-22T16:00:01.037 回答