ViewGroup заканчивают раздувать событие - PullRequest
8 голосов
/ 22 сентября 2011

Я создал пользовательский макет, который расширяет ViewGroup.Все работает нормально, и я получаю макет, как и ожидалось.

Я хочу динамически изменить элемент в макете.Однако это не работает, так как я называю это в onCreate, и до этого времени весь макет фактически не (нарисован) надувается на экран и, следовательно, не имеет фактического размера.

Есть ли какое-либо событие, которое может бытьиспользуется, чтобы узнать, когда раздувание макета сделано?Я пробовал onFinishInflate, но это не сработало бы, так как Viewgroup имеет несколько представлений, и это будет вызываться несколько раз.

Я думаю о создании интерфейса в классе Custom layout, но не уверен, когда его запускать?

Ответы [ 2 ]

26 голосов
/ 22 сентября 2011

Если я правильно понимаю ваши требования, 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.
            }
        });
2 голосов
/ 22 сентября 2011

Обычно при создании пользовательского макета с расширением 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) для каждого дочернего представления, содержащегося в нем. (measure () вызывается в onMeasure (), а layout () вызывается в onLayout ()).

В любом случае, в 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;
}
...