自定义Viewgroup在LinearLayout中工作,而不是在RelativeLayout中工作
我想创建一个自定义的 LinearLayout(以及后来的自定义 ImageButton),它可以根据其父级的大小获取两个尺寸尺寸的百分比值,而不管父级类型(相对或线性)。我正在关注这篇文章:如何调整尺寸Android 视图基于其父级的尺寸,它非常有帮助,但我有一个这些答案没有解决的问题。
当我将自定义 LinearLayout 放入另一个 LinearLayout 时,一切都会按预期工作。我的自定义 LinearLayout 覆盖了预期的空间(在下面的示例中为父级宽度的 80%)。
但是,如果我将它放在相对布局中,我的屏幕总是显示为空,我不确定为什么会发生这种情况。
这是我的课程:
public class ButtonPanel extends LinearLayout {
public ButtonPanel(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int newWidth = (int) Math.ceil(parentWidth * 0.8);
this.setMeasuredDimension(newWidth, parentHeight);
this.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,parentHeight));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
这是我的活动测试布局。
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.android.tests.views.ButtonPanel
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/inner_panel"
android:gravity="center_horizontal"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true">
</com.android.tests.views.ButtonPanel>
</RelativeLayout>
在我的活动中,我所做的就是将内容视图设置为上面的布局。
(顺便说一句,现在有人知道我如何动态获取父级的类型以设置新的 LayoutParameters 吗?在上面您将看到父级类型(RelativeLayout)硬编码到自定义视图 onMeasure 函数中)
提前感谢您的帮助!
I wanted to create a custom LinearLayout (and later a custom ImageButton) that could take percentage values for both dimensions of size based on its parent's size regardless of the parent type (Relative or Linear). I was following this post: How to size an Android view based on its parent's dimensions, and it was very helpful, but I have a problem that those answers don't address.
When I place my Custom LinearLayout inside another LinearLayout, everything works as expected. My Custom LinearLayout covers the expected space (80% of the parent's width in the example below).
However if I place it inside a RelativeLayout, my screen always shows empty, I am not sure why this happens.
Here is my class:
public class ButtonPanel extends LinearLayout {
public ButtonPanel(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int newWidth = (int) Math.ceil(parentWidth * 0.8);
this.setMeasuredDimension(newWidth, parentHeight);
this.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,parentHeight));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
And here is my testing layout for the activity.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.android.tests.views.ButtonPanel
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/inner_panel"
android:gravity="center_horizontal"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true">
</com.android.tests.views.ButtonPanel>
</RelativeLayout>
In my activity all I do is set the Content View to the above layout.
(Incidentally, does anybody now how I could get the type of the parent dynamically for setting the new LayoutParameters? Above you'll see the parent type (RelativeLayout) hard-coded into the Custom View onMeasure function)
Thanks in advance for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是否暴露出一个问题?
Is this exposed to be a problem?
在 onMeasure 函数中,您可以使用类似的方法来了解哪个类是视图的父类。
这也应该有效
,或者
当使用“instanceof”时,您需要在编译时知道“B”的类。当使用“isAssignableFrom”时,它可以是动态的并在运行时发生变化。
如果您不习惯字符串比较,也可以使用枚举。
In the onMeasure function you could use something like this to know what class is the parent of the view.
This should also work
or
When using "instanceof", you need to know the class of "B" at compile time. When using "isAssignableFrom" it can be dynamic and change during runtime.
If you are not compfortable with string comparison, you could also use enums.
事实证明,我在这篇文章中提出的两个问题比预期的更相关。
我意识到,通过将视图的 LayoutParams 设置为一个全新的实例,我覆盖了相对布局定位视图所需的布局定位信息。
通过“清零”该信息,我的视图具有正确的尺寸,但布局不知道将其放置在哪里,所以它根本不知道。
新 onMeasure 的以下代码显示了如何直接修改已附加到我的视图的 LayoutParams 的高度和宽度,从而避免覆盖布局位置信息并避免基于父级类型创建新的 LayoutParams。
现在,我要诚实地说,这段代码仍然不是没有错误的。多次将 Activity 置于前台和后台会不断减小此自定义视图的大小。每次启动 Activity 时都会反复应用 0.8 的缩减系数(我怀疑 LayoutParams 的设置与此有关,实际上可能没有必要,但我没有时间测试)。
但是,这仍然回答了有关这篇文章的问题,即为什么我的视图根本没有出现,尽管尺寸正确。
Turns out my two inquiries in this post were more related than expected.
I realized that by setting my view's LayoutParams to a completely new instance, I was overwriting the layout positioning information needed by the Relative Layout to position my view.
By 'zeroing out' that information, my view has the right dimensions, but the layout doesn't know where to place it, so it simply doesn't.
The following code for the new onMeasure shows how just directly modifying the height and width of the LayoutParams already attached to my view I avoid both overwriting the layout position information and having to create new LayoutParams based on the parent's type.
Now, I'll be honest and say that this code is still not bug-free. Bringing the activity to the foreground and background multiple times constantly reduces the size of this custom view. The 0.8 reduction factor gets applied over and over each time the activity is brought up (I suspect the setting of the LayoutParams has to do with it, it might actually be unnecessary, but I haven't has time to test).
BUT, this still answered the question concerning this post, namely, why was my view not appearing at all despite having the right dimensions.