在我的项目中,我有相同模式重复的屏幕 - 它基本上是视图的容器,包含带有标题,图像和特定背景的线性布局。为了避免多次复制和粘贴相同的序列,我认为我可以创建一个复合视图,扩展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>
答案 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。