是否可以在 onLayout 事件中将视图添加到布局?

发布于 2024-11-06 21:47:15 字数 293 浏览 7 评论 0原文

是否可以在其子级之一的 onLayout 事件期间向布局添加视图?

FrameLayout包含View,在View.onLayout()中我想将视图添加到父FrameLayout。

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

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

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夕嗳→ 2024-11-13 21:47:15

是的,这是可能的。我已经使用以下代码(覆盖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 中找到它的用法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文