我正在尝试创建一个包含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>