【问题标题】:Is it possible to add views to layout in onLayout event?是否可以在 onLayout 事件中向布局添加视图?
【发布时间】:2011-05-12 10:10:17
【问题描述】:

是否可以在其中一个 Childs 的 onLayout 事件期间向布局添加视图?

FrameLayout包含View,在View.onLayout()中我想给父FrameLayout添加view。

这是因为我需要在 FrameLayout 上绘制的视图需要子视图尺寸(宽度、高度)才能将它们分配到 FrameLayout 上的特定位置。

我已经尝试这样做了,但是什么都没有画出来。你知道我怎样才能达到同样的效果吗?或者如果我做错了什么。不知道为什么我无法绘制视图,如果我调用无效。

谢谢。

【问题讨论】:

  • onLayout 可以多次调用,因此添加子级可能不是明智之举。最好在开头添加它们,然后在 onLayout 中更改它们的位置/大小
  • 您好约瑟夫,感谢您的评论。我正在 onLayout 事件之外创建视图。但是,我无法在 onLayout 事件上更改其 LayoutParams,我需要这样做以便将此视图放在 FrameLayout 中的特定位置。有什么想法吗?
  • 因为现在视图正在显示,但总是在 FrameLayout 的左上角
  • 设置子元素的LayoutParams 不会有任何影响,除非您更改FrameLayout 的布局行为,因为它只会将子元素放置在左上角,而不管他们请求的位置。跨度>

标签: android android-framelayout


【解决方案1】:

是的,这是可能的。我已经使用以下代码(SeekBar 中的重写方法)解决了类似的问题(将检查点按钮放置在 SeekBar 上的 FrameLayout 中):

@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 方法时才能使用它),javadoc 说它的目的正是我们在这里讨论的,但我不明白为什么会这样比 addView() 更好。你可以在ListView找到它的用法。

猜你喜欢
  • 2021-12-01
  • 2015-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多