创建自定义 LinearLayout 并用视图填充它

Create custom LinearLayout and fill it with Views

我在 main.xml 文件中有一个主 LinearLayout,它在 Activity 中设置 (setContentView) ].进入主要 LinearLayout 我想添加 1-X 自定义 LinearLayouts。所以我创建了一个 XML "template" detail_line.xml :

<?xml version="1.0" encoding="utf-8"?>
<com.test.layout.DetailLine
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingBottom="@dimen/button_bottom_padding">

        <LinearLayout
            android:id="@+id/purpleLine"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:orientation="horizontal">

            <!-- programmatically add other views -->

        </LinearLayout>

        <!-- more "purpleLines" will be coming but for now it's not a point of interest -->

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingBottom="@dimen/detail_save_buttons"
        android:paddingTop="@dimen/detail_save_buttons">

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@android:color/darker_gray" />

    </LinearLayout>

</com.test.layout.DetailLine>

这是 Class:

    public class DetailLine extends LinearLayout {

    private Map<String, String> row;

    private Context context;

    public DetailLine(Context context) {
        super(context);
        this.context = context;
        this._create();
    }

    public DetailLine(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this._create();
    }

    public DetailLine(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        this._create();
    }

    /**
     * Inflates XML layout
     */
    private void _create() {
        this._purpleLine();
    }

    /**
     * Creates purple line
     */
    private void _purpleLine() {

        LinearLayout purpleLine = (LinearLayout) this.findViewById(R.id.purpleLine);
        purpleLine.removeAllViews(); // NullPointerException thrown here

// Add views...
    }
}

NullPointerException 在使用自定义 LinearLayout 的子视图时抛出。看起来 XML 和 Class 之间没有任何联系。我尝试调用 LayoutInflater.from(this.context).inflate(R.layout.detail_line, null);,但没有成功。我已经检查了教程 over here,但我并不聪明,而是对 <merge> 的东西感到困惑。

您正在 DetailLine 的构造函数中调用 _create(),但它还没有子项。您需要改写 onFinishInflate(),然后您可以访问其子项:

protected void onFinishInflate() {
    LinearLayout purpleLine = (LinearLayout) this.findViewById(R.id.purpleLine);
    purpleLine.removeAllViews();
    ...
}

我终于找到了正确答案。需要做的就是以不同的方式扩充 LinearLayout 文件并将自定义布局名称 (com.test.layout.DetailLine) 更改回 LinearLayout.

private void _create() {
    inflate(this.context, R.layout.detail_line, this);
    this._purpleLine();
}

致谢:http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/