Question

Is it possible to add views to a layout during the onLayout event of one of its Childs?

i.e.

FrameLayout contains View, in View.onLayout() I want to add views to the parent FrameLayout.

This is because the views I need to draw on the FrameLayout needs the child View dimensions (width, height) to assign them to particular positions on the FrameLayout.

I already try to do so, but nothing is getting drawn. Do you know how can I accomplish the same effect? or if I'm doing something wrong. Don't know why I'm unable to draw the views, event if I call invalidate.

Thanks.

Was it helpful?

Solution

Yes, it's possible. I have solved similar problem (placing a checkpoint Button into FrameLayout over SeekBar) using the following code (overriden methods from 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;
}

There is also ViewGroup.addViewInLayout() method (it's protected, so you can use it only if you override onLayout method of your Layout) which javadoc says its purpose is exactly what we discuss here, but I haven't understood why is it better than addView(). You can find it's usage in ListView.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top