我创建了一个扩展ViewGroup的自定义布局。一切都很好,我按预期得到布局。
我想动态更改布局中的元素。然而这不起作用,因为我在onCreate中调用它,直到那时整个布局实际上(绘制)没有膨胀到屏幕上,因此没有实际尺寸。
是否有任何事件可以用来找出布局的膨胀何时完成?我试过onFinishInflate但是这不起作用,因为Viewgroup有多个视图,这将被多次调用。
我正在考虑在Custom布局类中创建一个接口,但不确定何时触发它?
答案 0 :(得分:26)
如果我正确理解您的要求,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.
}
});
答案 1 :(得分:2)
通常在创建展开View
或ViewGroup
的自定义布局时,您必须覆盖protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
和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;
}