android - 带 child 的自定义 Android 控件

标签 android border android-linearlayout

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

如何将用户指定的内容(main.xml 中的 TextView)插入正确的位置 (id=container)?

干杯!

罗曼

-----编辑-------

仍然没有成功,所以我改变了我的设计以使用更简单的布局,并决定接受一些重复的 XML。尽管如此,仍然对任何知道如何执行此操作的人非常感兴趣!

最佳答案

这个确切的问题已经困扰了我一段时间,但直到现在我才解决了它。

乍一看,问题在于声明性内容(在您的情况下为 TextView)是在构造函数之后(我们通常会在其中扩充布局)实例化的,所以它太过分了early 手头有声明和模板内容,可以将前者插入后者。

我找到了一个这样的地方,我们可以在其中操纵两者:它是一个 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> 

关于android - 带 child 的自定义 Android 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4604066/

相关文章:

android - 使用 camera2 API 在视频输出文件中添加文本标签

android - 在 Android 上从 Azure 下载大文件

java - 方法调用仅适用于单击按钮

android - 更改屏幕方向时 EditText 中的值错误

html - border-radius 不再适用于动画图像

css - 从按钮 CSS 中删除边框?

android - 试图在 Android 中将按钮推到线性布局的底部

android - Android 中带有 layout_weight 的线性布局中的无边框按钮

html - Div边框不显示

java - Android动态设置textview的重力