XML中定义的扩展LinearLayout的子项不显示

时间:2013-03-18 23:19:07

标签: android android-linearlayout android-custom-view

在我的项目中,我有相同模式重复的屏幕 - 它基本上是视图的容器,包含带有标题,图像和特定背景的线性布局。为了避免多次复制和粘贴相同的序列,我认为我可以创建一个复合视图,扩展LinearLayout并在那里定义所有“样式”,然后在我的布局中使用该组件。 我按照howto和例子,让我的复合视图工作。但是,我看到的所有示例都使用结果视图,如下所示:

<com.myproject.compound.myview
    ...some attrs...
/>

即。没有通过XML添加子项。我需要像这样使用它:

<com.myproject.compound.myview
    ...some attrs...>
    <TextView 
        ..../>
    ...other views...

</com.myproject.compound.myview>

由于我正在扩展LinearLayout,我期待“myview”标签也像LinearLayout一样工作,但由于某些原因,我放在里面的项目不会被绘制。有什么我需要特别做的事情才能得到内部视图吗?

我的扩展LinearLayout非常简单,我没有覆盖任何方法,只是在构造函数中调用super并像这样膨胀布局:

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_compound_view, this, true);

更新:我以为我会添加一个XML作为参考点:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" 
android:background="@drawable/bg"
android:padding="12dp">
<TextView 
    android:id="@+id/section_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#FF0000AA"        />
<ImageView
    android:layout_width="match_parent"
    android:layout_height="2dp"
        android:src="@drawable/line"        />
</LinearLayout>

2 个答案:

答案 0 :(得分:10)

实际上找到了更优雅的解决方案。只需要在复合视图中使用merge标签而不是LinearLayout。所有归结为:

<merge xmlns:android="http://schemas.android.com/apk/res/android"
    <TextView 
        android:id="@+id/section_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="HEADING"
        android:textColor="#FF0000AA"        />
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:src="@drawable/line"        />
</merge>

public class CompoundLayout extends LinearLayout{
    public CompoundLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater inflater = (LayoutInflater) context
           .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.compound_layout, this, true);
    }
}

主要布局:

<com.testbench.CompoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFFFDDEE"
    android:orientation="vertical">
    <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Inner text"
            android:layout_gravity="center_horizontal"/>        
</com.testbench.CompoundLayout>

答案 1 :(得分:6)

在阅读了Android源代码和示例后,我想我认为这个问题就出来了。基本上在我的情况下,它是复合视图和自定义布局的混合体。 “复合视图”部分负责布局和绘制指定“容器”的XML的内容。但是该容器内的物品会在以后被充气,在我的实施中它们没有被布置。 一种方法是遵循自定义布局路径 - 我必须实现onLayout()和onMeasure()来正确计算我的孩子(我在研究过程中做过,它有效)。但是因为我真的不需要和LinearLayout已经有什么不同而且我不想复制/粘贴它的代码(那些方法很大),我只是决定覆盖onFinishInflate()方法并添加了我的“容器视图” “ 那里。这是整个代码,请评论是可以改进的。

public class CompoundLayout extends LinearLayout{
View mView;
public CompoundLayout(Context context, AttributeSet attrs) {
    super(context, attrs);

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mView = inflater.inflate(R.layout.compound_layout, this, false);
}

@Override
public void onFinishInflate(){
    super.onFinishInflate();
    addView(mView, 0);
}
}

然后在Activity的主要布局中,我使用自定义布局,就像使用LinearLayout一样。它渲染相同,但始终使用TextView和ImageView。