创建自定义LinearLayout并使用Views填充它

时间:2015-01-27 13:58:39

标签: android android-layout

我在 main.xml 文件中有一个主LinearLayout,它在Activity中设置(setContentView)。进入主LinearLayout我想添加1-X自定义LinearLayouts。所以我创建了一个XML"模板" 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>

这是班级:

    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...
    }
}
从自定义LinearLayout使用子视图时抛出

NullPointerException。看起来XML和Class之间没有任何联系。我试着打电话给LayoutInflater.from(this.context).inflate(R.layout.detail_line, null);,但没有成功。我已经查看了教程over here,但我并没有更聪明地对<merge>内容感到困惑。

2 个答案:

答案 0 :(得分:1)

我终于设法找到了正确的答案。所有需要做的就是以不同的方式膨胀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/

答案 1 :(得分:0)

您正在_create()的构造函数中调用DetailLine,当它还没有孩子时。您需要覆盖onFinishInflate(),然后才能访问其子项:

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