天天看點

Android自定義attr的各種坑

在開發Android應用程式中,經常會自定義View來實作各種各樣炫酷的效果,在實作這吊炸天效果的同時,我們往往會定義很多attr屬性,這樣就可以在XML中配置我們想要的屬性值,以下就是定義屬性值可能遇到的各種坑。

大家都知道怎麼定義attr屬性,一般如下:

<declare-styleable name="Sample">  
   <attr name="custom" format="string|reference" />
</declare-styleable>
           

先聲明一個styleable名稱,name名稱最好見名知義,一個styleable裡面可以有多個attr屬性,每一個attr都含有一個name,同時需要指明所能指派的類型,這是是依靠format來定義的。定義好之後就可以在自定義View中使用,來實作各種吊炸天的效果,使用如下:

xml中使用:

<com.sample.ui.widget.Custom   
     android:id="@+id/custom_view"  
     android:layout_width="130dp"  
     android:layout_height="130dp"  
     android:layout_gravity="center_horizontal" 
      android:layout_marginTop="90dp"  
     app:text="@string/custom_desc"  />
           

記得聲明 xmlns:app=”http://schemas.android.com/apk/res-auto”, app 可以随便取名 代碼中擷取值:

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Sample);
String value = a.getString(R.styleable.Sample.custom);
a.recycle();
           

根據format不同,還有getDimension,getColor等方式擷取值。

上面隻是描述了一般定義的方式,但他不是今天的主題,今天的主題是可能遇到的各種坑:

1:項目中隻包含一個attr.xml,出現 Attribute “custom” has already been defined

<declare-styleable name="Sample"> 
   <attr name="custom" format="string|reference" />
</declare-styleable>
<declare-styleable name="Sample1">
    <attr name="custom" format="string|reference" />
</declare-styleable>
           

如上聲明了兩個styleable,同時包含了相同的屬性custom,這時在編譯時會提示Attribute “xxx” has already been defined,表示相同屬性重複定義,相同styleable name不能再同一個attr.xml中重複定義,styleable name不一緻attir也不能重複定義,attr format屬性不影響重複定義結果。是以可以采用如下方法解決該問題:

a:重命名相同屬性名,将其中一個改為不同的名字

b:提取重複定義attr,作為公共屬性,方式如下:

<attr name="custom" format="string|reference" />
<declare-styleable name="Sample">
   <attr name="custom" />
</declare-styleable> 
<declare-styleable name="Sample1">  
  <attr name="custom" />
</declare-styleable>
           

2: 項目中引用了多個外部項目,出現 Attribute “custom” has already been defined

不同的導入項目中,可能包含多個attr.xml,這樣在定義時極有可能重複定義,他又分為如下兩種情況:

a: 主項目,引用庫包含同名styleable name,如:

主項目:

<declare-styleable name="Sample">
  <attr name="custom" />
</declare-styleable>
           

引用庫:

<declare-styleable name="Sample">
  <attr name="custom" />
</declare-styleable>
           

編譯時會出現 Attribute “custom” has already been defined。由此可以得出,在項目中引用各種庫,子產品時,各個不同的子產品定義attr,要遵循以下規則,

1:全部不能重複定義,全部不能重複很難實作,不同的團隊,不同的産品是極有可能重複定義,是以該方式很難實作。

2:各個不同子產品,定義時加上子產品字首,這種方式重複幾率就小很多,編譯時再将重複的重命名就ok了。