自定義View 篇二--------《自定義屬性》

之前在自定義View理論中,遺留下了一個知識,就是具體的自定義屬性到底怎麼使用。本篇就對自定義屬性的常見方式,做詳細的整理。分析自定義屬性的常見三種方式。



我們知道,大部分情況我們的自定義View需要有更多的靈活性,比如我們在xml中指定了顏色大小等屬性,在程序運行時候控件就能展示出相應的顏色和大小。所以我們需要自定義屬性。我們還知道,當在佈局文件中加入某個控件的時候,會調用該View的構造方法   XXXView(Context context,AttributeSet attribute);當我們在 xml中創建了一個view時,xml會被解析,顯示解析用pull解析xml文件,解析成鍵值對,對象的封裝成AttributeSet 對象;根據元素名,有類的全名就可以反射實例化該類,得到AttributeSet 該類,就得到屬性值。我們只需要在這個參數中就可以獲取所有自定義的屬性值了。


如何自定義屬性?

在自定義屬性前,先看看系統是怎麼定義屬性的。(查看View類的屬性)

找到系統attrs目錄:

D:\prograssinstall\as\SDK\platforms\android-23\data\res\values,點擊打開。

看一下View類的屬性情況:

<declare-styleable name="View">

        <!-- Supply an identifier name for this view, to later retrieve it

             with {@link android.view.View#findViewById View.findViewById()} or

             {@link android.app.Activity#findViewById Activity.findViewById()}.

             This must be a

             resource reference; typically you set this using the

             <code>@+</code> syntax to create a new ID resources.

             For example: <code>android:id="@+id/my_id"</code> which

             allows you to later retrieve the view

             with <code>findViewById(R.id.my_id)</code>. -->

        <attr name="id" format="reference" />


        <!-- Supply a tag for this view containing a String, to be retrieved

             later with {@link android.view.View#getTag View.getTag()} or

             searched for with {@link android.view.View#findViewWithTag

             View.findViewWithTag()}.  It is generally preferable to use

             IDs (through the android:id attribute) instead of tags because

             they are faster and allow for compile-time type checking. -->

        <attr name="tag" format="string" />


        <!-- The initial horizontal scroll offset, in pixels.-->

        <attr name="scrollX" format="dimension" />


        <!-- The initial vertical scroll offset, in pixels. -->

        <attr name="scrollY" format="dimension" />


        <!-- A drawable to use as the background.  This can be either a reference

             to a full drawable resource (such as a PNG image, 9-patch,

             XML state list description, etc), or a solid color such as "#ff000000"

            (black). -->

        <attr name="background" format="reference|color" />


        <!-- Sets the padding, in pixels, of all four edges.  Padding is defined as

             space between the edges of the view and the view's content. A views size

             will include it's padding.  If a {@link android.R.attr#background}

             is provided, the padding will initially be set to that (0 if the

             drawable does not have padding).  Explicitly setting a padding value

             will override the corresponding padding found in the background. -->

        <attr name="padding" format="dimension" />

.........................................

<attr name="background" format="reference|color" />舉例,這裏制定了屬性名稱,以及該屬性的類型是引用類型和color類型。類型代表,我可以通過什麼方式給屬性賦值。比如我們通常設置背景可以這麼寫:background="@R.drawable/a.png";或者background="#ff0000".相信,看到這裏肯定能夠意會了吧。

細心的你,會發現每一個配置文件中有一行命名間:xmlns:Adroid="http://schemas.android.com/apk/res/android"  這是系統自帶的,它的原理是:通過命名空間的前綴android,找到包的信息(這裏是最後一個名稱android),通過包的信息,找到工程,找到工程後。就可以找到這個工程的資源信息(values----attrs屬性配置文件),從attrs文件裏找到屬性配置的信息。


瞭解了系統的定義屬性原理,我們開始自定屬性。標準的步驟如下:


1_創建工程:包名:com.itydl.a06attributetest

建議用UTF-8編碼

2_創建屬性類MyAttributeView繼承View

3_創建工程的屬性文件attrs.xml和常見屬性類型


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
xmlns:itydl="http://schemas.android.com/apk/res-auto"
   
android:id="@+id/activity_main"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
tools:context="com.itydl.a06attributetest.MainActivity">

   <com.itydl.a06attributetest.MyAttributeView
       
itydl:my_age ="25dp"
       
itydl:my_name="android_attribute"
       
itydl:my_bg="@drawable/test"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
/>
</RelativeLayout>

其中itydl是自己的命名空間。

4_使用自定義類和自定義屬性

在res/values/下新建attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   
<!-- 定義一個名字叫MyAttributeView屬性集合,name往往跟對應的View的類名一致 -->
   
<declare-styleable name="MyAttributeView">
       
       
<!--定義一個類型爲integer,名字叫my_age的屬性  -->
       
<attr name="my_age" format="integer"/>
       
       
<!--定義一個類型爲string,名字叫my_name的屬性  -->
       
<attr name="my_name" format="string"/>

       
<!--定義一個類型爲referencecolor(這樣背景可以通過R引用,
也可以使用圖片資源)
,名字叫my_bg的屬性  -->
       
<attr name="my_bg" format="reference|color"/>
   </declare-styleable>
</resources>

5_三種方式得到屬性值

// 1.用命名空間取對應的屬性- String

String name = attrs.getAttributeValue(
      "http://schemas.android.com/apk/res-auto",
      "my_name");
String my_age = attrs.getAttributeValue(
      "http://schemas.android.com/apk/res-auto",
      "my_age");
String my_bg = attrs.getAttributeValue(
      "http://schemas.android.com/apk/res-auto",
      "my_bg");
// System.out.println(name+","+my_age+","+my_bg);


// 2.遍歷方式取屬性String 和int
for (int i = 0; i < attrs.getAttributeCount(); i++) {
  System.out.println(attrs.getAttributeValue(i) + ":"
       + attrs.getAttributeName(i));
}


// 3.用系統工具TypedArray取屬性- 取各種值Bitmap String 等等

//參數1:自定義屬性集合類;參數2:自動生成的自定義屬性類名稱的資源id(它是一個數組)
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyAttributeView);

//a.getIndexCount()獲取屬性個數
for (int i = 0; i < a.getIndexCount(); i++) {
    int index = a.getIndex(i);//所有屬性對應的id
    switch (index) {
        case R.styleable.MyAttributeView_my_age://年齡屬性id與之匹配
            mAgeInt = a.getInt(i, 0);
            break;
        case R.styleable.MyAttributeView_my_name://姓名
            mName = a.getString(i);
            break;
        case R.styleable.MyAttributeView_my_bg://背景圖片id
            //拿到圖片,Drawable類型
            Drawable drawable = a.getDrawable(i);
            //我們需要的bitmap類型的圖片
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            mBitmap = bitmapDrawable.getBitmap();
            break;

        default:
            break;
    }
}



6_把取到的屬性值給給畫出來
@Override
protected void onDraw(Canvas canvas) {
    canvas.drawText(mName + "-------------" + mAgeInt,50,50,mPaint);

    canvas.drawBitmap(mBitmap,50,50,mPaint);
}

format 常用類型

 

reference    引用

color    顏色

boolean    布爾值

dimension    尺寸值

float    浮點值

integer    整型值

string   字符串

enum   枚舉

 

具體使用情況可以google~

有點幫助的話可以關注哈,有問題大家一起交流。也可以動手微信掃描下方二維碼查看更多安卓文章:


打開微信搜索公衆號  Android程序員開發指南  或者手機掃描下方二維碼 在公衆號閱讀更多Android文章。

微信公衆號圖片:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章