自定义Viewgroup在LinearLayout内部工作,而不是RelativeLayout

时间:2011-10-04 02:55:08

标签: android layout custom-view

我想创建一个自定义LinearLayout(以及后来的自定义ImageButton),无论父类型(相对或线性)如何,都可以根据父级的大小获取两个大小维度的百分比值。我正在关注这篇文章:How to size an Android view based on its parent's dimensions,这非常有帮助,但我有一个问题,那些答案没有解决。

当我将自定义LinearLayout放在另一个LinearLayout中时,一切都按预期工作。我的自定义LinearLayout覆盖了预期的空间(在下面的示例中为父宽度的80%)。

但是如果我把它放在RelativeLayout中,我的屏幕总是显示为空,我不知道为什么会这样。

这是我的班级:

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)硬编码到Custom View onMeasure函数中)

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

这是否存在问题?

this.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,parentHeight)); // <-- a RelativeLayout params?

答案 1 :(得分:0)

在onMeasure函数中,您可以使用类似的东西来了解哪个类是视图的父级。

this.getParent().getClass().getName()

这也应该有用

a instanceof B

B.class.isAssignableFrom(a.getClass())

使用“instanceof”时,需要在编译时知道“B”类。使用“isAssignableFrom”时,它可以是动态的,并在运行时更改。

如果你不熟悉字符串比较,你也可以使用枚举。

答案 2 :(得分:0)

原来我在这篇文章中的两个问题与预期相关的更多。

我意识到通过将我的视图的LayoutParams设置为一个全新的实例,我覆盖了相对布局所需的布局定位信息来定位我的视图。

通过“清零”该信息,我的视图具有正确的尺寸,但布局不知道放置它的位置,所以它根本就没有。

新onMeasure的以下代码显示了如何直接修改已附加到我的视图的LayoutParams的高度和宽度我避免覆盖布局位置信息并且必须根据父类型创建新的LayoutParams。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int specWidth = MeasureSpec.getSize(widthMeasureSpec);
        int specHeight = MeasureSpec.getSize(heightMeasureSpec);

        int newWidth = (int) Math.ceil(parentWidth * 0.8);
        int newHeight = (int) Math.ceil(parentHeight * 0.8);

        this.setMeasuredDimension(newWidth, newHeight);

        this.getLayoutParams().height = newHeight;
        this.getLayoutParams().width = newWidth;

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

现在,我会诚实地说,这段代码仍然没有错误。将活动多次置于前台和背景会不断减少此自定义视图的大小。每次启动活动时都会反复应用0.8减少因子(我怀疑LayoutParams的设置与它有关,实际上可能没必要,但我没有时间测试)。

但是,这仍然回答了有关这篇文章的问题,即为什么我的观点根本没有出现,尽管有正确的尺寸。