自定义视图样式,android的属性被忽略

时间:2014-06-12 10:43:10

标签: android android-custom-view android-styles

我创建了一个自定义复合视图 - 视图加载,没有崩溃,到目前为止一直很好。

现在,我打算在我的应用中多次使用此视图,因此视图需要一种风格。

我在attr.xml文件中声明了它的样式

  <declare-styleable name="MyCustomView">

        <attr name="ff_label" format="string" />
        <attr name="ff_fieldText" format="string" />
    </declare-styleable>

    <declare-styleable name="MyCustomViewStyle">
        <attr name="customViewStyle" format="reference" />
    </declare-styleable>

然后我去了我的主题文件并在

中写了这个
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">

    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    //bunch of other stuff
    <item name="customViewStyle">@style/customViewStyle</item>
</style>

然后在我的android清单中声明了

<application
        android:name="com.my.app.App"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

然后在我编写的styles.xml文件中

   <style name="customViewStyleStyle" parent="@android:style/Widget.EditText">
        <item name="android:paddingBottom">@dimen/space_between_adjacent_widgets_vertical</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="ff_label">@string/default_label_text</item>
        <item name="ff_fieldText">@string/default_label_text</item>
    </style>

我的问题:我的OWN属性被认可得很好 为什么标记为"android:..."的属性会被忽略?

MyCustomView.java

public MyCustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
    initAttributes(context, attrs, R.attr.customViewStyle);
}

public MyCustomView(Context context) {
    super(context);
    initAttributes(context, null, R.attr.customViewStyle);
}

private void initAttributes(Context context, AttributeSet attrs, int defStyle) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.custom_view, this, true);
    label = (TextView) findViewById(R.id.label);
    formField = (EditText) findViewById(R.id.formField);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle,0);

    if (a.hasValue(R.styleable.MyCustomView_ff_label)) {
        labelText = a.getString(R.styleable.MyCustomView_ff_label);
        label.setText(labelText);
    }


    if (a.hasValue(R.styleable.MyCustomView_ff_fieldText)) {
        fieldText = a.getString(R.styleable.MyCustomView_ff_fieldText);
        field.setHint(fieldText);
    }


    a.recycle();
}

layout.xml

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

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

   <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
          />

    <include layout="@layout/layout_set_default" />

</TableLayout>

1个视图的默认高度约为30 dp - &gt;我不能使用列表视图。 它应该在每个视图之间有10dp填充

1 个答案:

答案 0 :(得分:5)

你必须像这里更改MyCustomView的代码:

    ...
    public MyCustomView(Context context, AttributeSet attrs) {
            //Called by Android if <com.my.app.MyCustomView/> is in layout xml file without style attribute.
            //So we need to call MyCustomView(Context context, AttributeSet attrs, int defStyle) 
            // with R.attr.customViewStyle. Thus R.attr.customViewStyle is default style for MyCustomView.
            this(context, attrs, R.attr.customViewStyle);
    }

    public MyCustomView(Context context) {
            this(context, null);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
            //Called by Android if <com.my.app.MyCustomView/> is in layout xml with style attribute
            // For example:
            //         <com.my.app.MyCustomView
            //                android:layout_width="match_parent"
            //                android:layout_height="wrap_content"
            //                style="@style/customViewStyleStyle"
            //                />
            //
            super(context, attrs, defStyle);
            initAttributes(context, attrs, defStyle);
    }
    ...

然后您可以在layout.xml中使用样式属性,而customViewStyle也可以是MyCustomView的默认样式。与textViewStyle相同的是TextView

的默认样式
    <com.my.app.MyCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/customViewStyleStyle"
      />

以前你有构造函数:

public MyCustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
    initAttributes(context, attrs, R.attr.customViewStyle);
}

正如您所看到的,您已将R.attr.customViewStyle传递给initAttributes()方法,但未将其传递给父构造函数。