无法从LayoutInflater访问自定义属性

时间:2014-02-05 04:22:39

标签: android android-layout android-custom-view

我创建了一个自定义视图(AuditQuestionEntry),它继承了LinearLayout,并在我的主要活动(AuditActivityTEST)中使用了这个自定义视图。因此,在AuditActivityTEST的onCreate方法中,setContentview调用AuditQuestionEntry构造函数,我只能通过命名空间访问自定义属性。但是,除非我在AuditQuestionEntry中专门膨胀视图,否则不会显示该自定义视图。如何调用构造函数但实际上不显示视图?

为了显示视图,我发现我需要在AuditQuestionEntry中使用LayoutInflater。当通过inflater调用构造函数时,我根本无法访问属性 - 甚至不能通过命名空间。

这是我的主要活动 - AuditActivityTEST

public class AuditActivityTEST extends BaseWorkbenchActivity {

// Collection of audit questions
AuditQuestionEntry AuditQuestion1;

@Override
public void onCreate(Bundle savedInstanceState) {
    // Set the context in the base class to be used for dialogs and other misc items
    CurrentContext = AuditActivityTEST.this;

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_audit_test);

    // Set audit questions =====================================================
    AuditQuestion1 = (AuditQuestionEntry) findViewById(R.id.auditQuestionEntry10);
    AuditQuestion1.InitAuditQuestion();

     OnClickListener btnPhotoListener = new OnClickListener() {

        @Override
        public void onClick(final View v) {
            View viewParent = (View) v.getParent();             
            AuditQuestionEntry clickedAudit = (AuditQuestionEntry) viewParent;

            Toast.makeText(CurrentContext, "Audit Question #" + clickedAudit.AuditQuestionNumber, Toast.LENGTH_SHORT).show();
        }

     };

    // ((Button) AuditQuestion1.findViewById(R.id.btnTakeAuditPhoto)).setOnClickListener(btnPhotoListener);
}    
}

以下是主要活动的关联布局文件 - activity_audit_test.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:workbench="http://schemas.android.com/apk/com.example.viewtestapp"
    android:id="@+id/scrollView111"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="30dp"
    tools:context=".AuditActivityTEST" >

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical|center_horizontal"
        android:paddingBottom="15dp"
        android:paddingTop="10dp"
        android:text="Current Closet Audit"
        android:textSize="24sp"
        android:textStyle="bold" />

    <com.example.viewtestapp.AuditQuestionEntry
        android:id="@+id/auditQuestionEntry10"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        workbench:AuditQuestionNumber="100"
        workbench:extraInformation="My extra information" >
    </com.example.viewtestapp.AuditQuestionEntry>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="30dp"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="Finished Audit? Click the following button to submit..."
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold" />
    </LinearLayout>
</LinearLayout>
</ScrollView>

以下是自定义视图 - AuditQuestionEntry.java

public class AuditQuestionEntry extends LinearLayout {

// misc parameters removed for brevity

public AuditQuestionEntry(Context context) {
    super(context);
    // InflateView();

    throw new RuntimeException("Missing AuditQuestionNumber");
}

public AuditQuestionEntry(Context context, AttributeSet attrs) {
    super(context, attrs);

    this._ctx = context;

    initAttributes(attrs);
}

// Used to grab the AuditQuestionNumber attribute from the XML declaration
private void initAttributes(AttributeSet attrs) {
TypedArray a =getContext().obtainStyledAttributes(attrs,R.styleable.AuditQuestionEntry);

    //AuditQuestionNumber = attrs.getAttributeIntValue("http://schemas.android.com/apk/com.example.viewtestapp","AuditQuestionNumber", 0);
    AuditQuestionNumber = a.getInteger(R.styleable.AuditQuestionEntry_AuditQuestionNumber, -1);

    // Don't forget this
    a.recycle();
}

public void InitAuditQuestion() {

    InflateView();
}

public void InflateView() {
    // Setup the infalter
    LayoutInflater layoutInflater;

    layoutInflater = (LayoutInflater) getContext().getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);

    // Inflate the resource in the context of this view and automatically attach
    layoutInflater.inflate(R.layout.audit_question_entry, this);
}
}

最后,这是attrs.xml

<resources>
    <declare-styleable name="AuditQuestionEntry">
        <attr name="AuditQuestionNumber" format="integer" />
    </declare-styleable>
</resources>

总之,我的问题是:

  1. 如果setContentView调用AuditQuestionEntry构造函数,为什么自定义视图不显示,我是否需要实际需要通过LayoutInflater进行充气?
  2. 为什么自定义属性不能通过obtainStyledAttributes获得,而是通过命名空间方法?
  3. 我知道这很多,但我想确保我解释并包含所有内容。

1 个答案:

答案 0 :(得分:0)

// try this way
public class AuditQuestionEntry extends LinearLayout {
    public int AuditQuestionNumber;
    public AuditQuestionEntry(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    public AuditQuestionEntry(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public AuditQuestionEntry(Context context) {
        super(context);
        init(null);
    }

    private void init(AttributeSet attrs) {
        String namespace = "http://schemas.android.com/apk/" + getContext().getPackageName();
        AuditQuestionNumber = attrs.getAttributeIntValue(namespace, "AuditQuestionNumber", -1);
        View view = LayoutInflater.from(getContext()).inflate(R.layout.audit_question_entry, null, false);
        addView(view);
    }

}