Можно ли добавить представления к макету в событии onLayout? - PullRequest
2 голосов
/ 12 мая 2011

Можно ли добавить представления в макет во время события onLayout одного из его дочерних объектов?

т.е.

FrameLayout содержит View, в View.onLayout () я хочу добавить представленияк родительскому FrameLayout.

Это потому, что представления, которые мне нужно нарисовать на FrameLayout, нуждаются в дочерних измерениях View (ширина, высота), чтобы назначить их определенным позициям в FrameLayout.

Iуже пытаюсь это сделать, но ничего не получается.Вы знаете, как я могу добиться того же эффекта?или если я делаю что-то не так.Не знаю, почему я не могу нарисовать представления, событие, если я назову недействительным.

Спасибо.

1 Ответ

3 голосов
/ 11 августа 2011

Да, это возможно.Я решил аналогичную проблему (поместив кнопку контрольной точки в FrameLayout поверх SeekBar), используя следующий код (переопределенные методы из SeekBar):

@Override
protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) {
  super.onLayout(changed, left, top, right, bottom);
  View child = new Button(getContext());

  //child measuring
  int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, 0, LayoutParams.WRAP_CONTENT); //mWidthMeasureSpec is defined in onMeasure() method below
  int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);//we let child view to be as tall as it wants to be
  child.measure(childWidthSpec, childHeightSpec);

  //find were to place checkpoint Button in FrameLayout over SeekBar
  int childLeft = (getWidth() * checkpointProgress) / getMax() - child.getMeasuredWidth();

  LayoutParams param = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
  param.gravity = Gravity.TOP;
  param.setMargins(childLeft, 0, 0, 0);

  //specifying 'param' doesn't work and is unnecessary for 1.6-2.1, but it does the work for 2.3
  parent.addView(child, firstCheckpointViewIndex + i, param);

  //this call does the work for 1.6-2.1, but does not and even is redundant for 2.3
  child.layout(childLeft, 0, childLeft + child.getMeasuredWidth(), child.getMeasuredHeight());
}

@Override
protected synchronized void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)    {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  //we save widthMeasureSpec in private field to use it for our child measurment in onLayout()
  mWidthMeasureSpec = widthMeasureSpec;
}

Существует также метод ViewGroup.addViewInLayout () (он защищен, поэтому вы можете использовать его, только если вы переопределите метод onLayout вашего Layout), который, по словам javadoc, предназначен именно для того, что мы здесь обсуждаем, но я не понял, почему он лучше, чем addView ().Вы можете найти его использование в ListView .

...