AttributeSet與TypeArray的關係

相信大家都對這連個比較好奇,我們在實現自定義View的時候,常常使用TypeArray來加載xml屬性值,那麼在自定義View的構造方法中AttributeSet也出現了,那麼他的出現有什麼用呢,我們來具體看一下

先在Value裏面新建attrs.xml文件
文件定義如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView">
        <attr name="textSize" format="integer"></attr>
        <attr name="textColor" format="reference|color"></attr>
    </declare-styleable>
</resources>

下面是Activity_mainde佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:user="http://schemas.android.com/apk/res/com.example.fang.myapplication"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.fang.myapplication.MainActivity">

    <com.example.fang.myapplication.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        user:textColor="@color/colorAccent"
        user:textSize="20" />

</LinearLayout>

在上面是自定義View,在linearlayout中我們定義了一個命名空間,地址是http://schemas.android.com/apk/res/自己的完整包名;

接着我們新建MyView繼承View具體代碼如下

package com.example.fang.myapplication;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;



/**
 * Created by fang on 2017/11/10.
 */

public class MyView extends View {

   String TAG="main";
    public MyView(Context context) {
        this(context,null);

    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
          int count= attrs.getAttributeCount();
        for(int i=0;i<count;i++){
          String name=  attrs.getAttributeName(i);
            String value=attrs.getAttributeValue(i);
            Log.d(TAG, "name="+name+""+"vslue="+value);
        }

    }

}

打印結果是什麼呢:我們來看一下這裏寫圖片描述
我們發現答打印了倆行,對應與我們的個屬性,即layout_width,
layout_height,textSize,textColor,我們發現通過A他tributeSet訪問我們定義View的屬性值,只不過奇怪的是我們發現textColor的值居然是亂七八糟的東西,也不知道是什麼鬼,那麼,這是什麼原因呢,我也不清楚,看下官方文檔:
A collection of attributes, as found associated with a tag in an XML document. Often you will not want to use this interface directly, instead passing it to Resources.Theme.obtainStyledAttributes() which will take care of parsing the attributes for you. In particular, the Resources API will convert resource references (attribute values such as “@string/my_label” in the original XML) to the desired type for you;
大致意思是,該類是個屬性的集合,與xml文件相關聯的文檔,我們通常不直接使用這個類也是使用Resources.Theme.obtainStyledAttributes()來加載屬性,特別是,資源API將把資源引用(原始XML中的“@ string/ my_label”屬性值)轉換爲所需類型。
那麼我們在在來試試使用TypeArray來加載,我們將構造方法中的代碼進行修改

   public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray type = getResources().obtainAttributes(attrs, R.styleable.MyView);
        int count = type.getIndexCount();
        for (int i = 0; i < count; i++) {
            int index=type.getIndex(i);
            if(index==R.styleable.MyView_textSize){
              int size= type.getInt(index,-1);
                Log.d(TAG,"size="+size);
            }
           if(index==R.styleable.MyView_textColor){
               String color=type.getString(index);
               Log.d(TAG,"color="+color);
           }
        }
    }

打印結果如下
這裏寫圖片描述

我們發現剛剛用AttaibuteSet解析資源引用時出現一大堆數字的情況消失了,很興奮,現在我們可以推測,TypeArray就是對Attribute的再包裝

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