2014-06-12 105 views
3

我創建了一個自定義複合視圖 - 視圖加載,沒有崩潰,到目前爲止這麼好。自定義視圖風格,android的屬性被忽略

現在,我計劃在我的應用中使用這個視圖很多次,所以視圖需要一個樣式。

我宣佈爲它設置樣式在我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 - >我不能使用它的列表視圖。 它應該有每個視圖之間10dp填充

+0

關於[在Android中定製自定義視圖]的寫文章(http://onetouchcode.com/2016/11/25/styling-custom-views-android/)。 – Shailendra

回答

4

你必須改變的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.customViewStyleinitAttributes()方法,但不要把它傳遞給父類的構造。

+0

我添加了一個主題,我寫道,我將主題添加到應用程序 我寫道「我自己的」屬性被識別。什麼被忽略是「android:bottomPadding」爲什麼? –

+0

該帖子一步步顯示我如何添加他們 - 主題作品。只是如果我把自定義風格「正常」的Android屬性,他們被忽略...... –

+0

您的文章是非常翔實的,但你可以添加你的佈局XML和活動代碼? – olegr