我正在尝试创建一个包含LinearLayout的自定义
Android控件.您可以将其视为具有花哨边框的扩展LinearLayout,背景,左侧的图像…
我可以在XML中完成所有工作(效果很好),但是由于我的应用程序中有几十次出现,所以很难维护.我以为这样做会更好一些:
/* Main.xml */
<MyFancyLayout>
<TextView /> /* what goes inside my control's linear layout */
</MyfancyLayout>
你会如何处理这个?我想避免重写整个线性布局onMeasure / onLayout方法.这是我现在所拥有的:
/* MyFancyLayout.xml */
<TableLayout>
<ImageView />
<LinearLayout id="container" /> /* where I want the real content to go */
</TableLayout>
和
/* MyFancyLayout.java */
public class MyFancyLayout extends LinearLayout
{
public MyFancyLayout(Context context) {
super(context);
View.inflate(context,R.layout.my_fancy_layout,this);
}
}
您将如何在正确的位置(id = container)中插入用户指定的内容(main.xml中的TextView)?
干杯!
罗曼
—–编辑——-
仍然没有运气,所以我改变了我的设计,使用一个更简单的布局,并决定生活与一些重复的XML.对任何人仍然很有兴趣知道如何做到这一点!
解决方法
这个确切的问题已经让我有一段时间了,但现在我已经解决了这个问题.
乍一看,问题在于,在ctor之后的某个时间(在我们通常会膨胀我们的布局)的时候,声明性内容(您的案例中的TextView)被实例化,所以现在还有声明和模板内容的时间太早了将前者推入后者.
我找到了一个这样的地方,我们可以操纵这两个:这是一个onFinishInflate()方法.以下是我的情况:
@Override
protected void onFinishInflate() {
int index = getChildCount();
// Collect children declared in XML.
View[] children = new View[index];
while(--index >= 0) {
children[index] = getChildAt(index);
}
// Pressumably,wipe out existing content (still holding reference to it).
this.detachAllViewsFromParent();
// Inflate new "template".
final View template = LayoutInflater.from(getContext())
.inflate(R.layout.labeled_layout,this,true);
// Obtain reference to a new container within "template".
final ViewGroup vg = (ViewGroup)template.findViewById(R.id.layout);
index = children.length;
// Push declared children into new container.
while(--index >= 0) {
vg.addView(children[index]);
}
// They suggest to call it no matter what.
super.onFinishInflate();
}
以上引用的labeled_layout.xml与此不同:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation ="vertical"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:layout_marginLeft ="8dip"
android:layout_marginTop ="3dip"
android:layout_marginBottom ="3dip"
android:layout_weight ="1"
android:duplicateParentState ="true">
<TextView android:id ="@+id/label"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:singleLine ="true"
android:textAppearance ="?android:attr/textAppearanceMedium"
android:fadingEdge ="horizontal"
android:duplicateParentState="true" />
<LinearLayout
android:id ="@+id/layout"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:layout_marginLeft ="8dip"
android:layout_marginTop ="3dip"
android:duplicateParentState="true" />
</LinearLayout>
现在(仍然省略一些细节)在别的地方我们可以这样使用它:
<com.example.widget.LabeledLayout
android:layout_width ="fill_parent"
android:layout_height ="wrap_content">
<!-- example content -->
</com.example.widget.LabeledLayout>

