1. 程式人生 > >Android 自定義View 中attr屬性 深入解析

Android 自定義View 中attr屬性 深入解析

一、attr和styleable

自定義View,如果想在xml指定引數(例如:改變字型顏色,字型大小),需要宣告一個styleable,並在裡面自己定義一些attr屬性。

attr不依賴於styleable,styleable只是為了方便attr的使用。

不使用styleable

自定義屬性完全可以不放到styleable裡面,比如直接在resources檔案中定義一些屬性:

<attr name="custom_attr1" format="string" />
<attr name="custom_attr2" format="string" />

一個attr對應R檔案的一個id,使用下面的方式獲取屬性

int[] custom_attrs = {R.attr.custom_attr1,R.custom_attr2};
TypedArray typedArray = context.obtainStyledAttributes(set,custom_attrs);

使用styleable

定義一個styleable,在R檔案裡會自動生成一個int[],數組裡面的int就是定義在styleable裡面attr的id。所以我們在獲取屬性的時候就可以直接使用styleable陣列來獲取一系列的屬性。

<declare-styleable name="custom_attrs"
>
<attr name="custom_attr1" format="string" /> <attr name="custom_attr2" format="string" /> </declare-styleable>

獲取:

  TypedArray typedArray = context.obtainStyledAttributes(set,R.styleable.custom_attrs);

定義一個declare-styleable,自動提供了一個屬性陣列,使用這個陣列獲取屬性。此外,我覺得使用declare-styleable的方式有利於把相關的屬性組織起來,有一個分組的概念,屬性的使用範圍更加明確。

二、改變屬性值

屬性值的改變,有下面五種方式:

1、在xml中設定屬性值
2、在xml中設定style
3、在Theme中設定style
4、在Theme中設定屬性值
5、自定義view中設定預設style

三、obtainStyledAttributes()獲取屬性

既然上面設定屬性的值,有5個地方,那麼獲取屬性的值,也會有5個地方(見下面藍色字樣),且分優先順序。

在前面已經使用了obtainStyledAttributes來獲取屬性了,現在來看看這個函式的宣告吧:

//從xml中獲取attrs中屬性的值
obtainAttributes(AttributeSet set, int[] attrs); 

//從Theme中獲取attrs中屬性的值
obtainStyledAttributes(int[] attrs); 

//從資原始檔定義的style中讀取屬性 
obtainStyledAttributes(int resId,int[] attrs); 

//多個數據源
obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes);

獲取屬性,引數主要分為兩類:第一,我需要獲取哪些屬性;第二:我從哪裡去獲取這些屬性(資料來源)。

attrs

attrs:int[],每個方法中都有的引數,就是告訴系統需要獲取哪些屬性。

set

set:表示從xml檔案為這個View新增的屬性。注意,由LayoutInflater載入進來的佈局或者View才有這個屬性集。

兩種資料來源:

  • 使用android:layout_width=”wrap_content”直接指定,1、在xml中設定屬性值
  • 通過style=”@style/somestyle”指定的。2、在xml中設定style

defStyleAttr

3、在Theme中設定style

在系統Theme設定style ,修改所有的樣式,一般會這麼做:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="custom_style">@style/custom_theme</item>
</style>
<style name="custom_theme">
        <item name="custom_color1">#36a39b</item>
        <item name="custom_color2">#36a39b</item>
        <item name="custom_color3">#36a39b</item>
</style>

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

上面程式碼中的custom_style 是style 名稱,custom_theme是style 的內容

public CustomView(Context context, AttributeSet attrs) {
        //defStyleAttr引數的值為 R.attr.custom_style
        this(context, attrs, R.attr.custom_style);
}

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //呼叫了obtainStyledAttributes的四參函式
        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.custom_attrs, defStyleAttr, R.style.default_style);
}

resId=defStyleRes

5、自定義view中設定預設style

resId or defStyleRes:直接從資原始檔定義的style中獲取屬性值。

<style name="default_style">
        <item name="custom_color1">#909304</item>
        <item name="custom_color2">#909304</item>
        <item name="custom_color3">#909304</item>
        <item name="custom_color4">#909304</item>
        <item name="custom_color5">#909304</item>

 </style>
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //呼叫了obtainStyledAttributes的四參函式
        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.custom_attrs, defStyleAttr, R.style.default_style);
}

obtainStyledAttributes(int[] attrs);

這個函式並未指定資料來源,他是在Theme中獲取指定屬性的值。4、在Theme中設定屬性值

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="custom_color1">#32b430</item>
        <item name="custom_color2">#32b430</item>
        <item name="custom_color3">#32b430</item>
        <item name="custom_color4">#32b430</item>

    </style>

TypedArray

我們看到在獲取到屬性值之後,都會返回一個TypedArray物件,它又是什麼鬼?

TypedArray主要有兩個作用,

  • 第一是內部轉換attrid和屬性值陣列的關係;
  • 第二是提供了一些型別的自動轉化,比如我們getString時,TypedArray會自動將ResId對應的string從資原始檔中讀出來。

四、優先順序

優先順序從高到低:

  1. 在xml中設定屬性值
  2. 在xml中設定style
  3. 在Theme中設定style
    • 不為0, 則不使用 自定義view中設定的預設style
    • 為0,使用自定義view中設定的預設style
  4. 在Theme中設定屬性值

五、程式碼

關注我的公眾號,輕鬆瞭解和學習更多技術
這裡寫圖片描述

相關推薦

Android 定義View attr屬性 深入解析

一、attr和styleable 自定義View,如果想在xml指定引數(例如:改變字型顏色,字型大小),需要宣告一個styleable,並在裡面自己定義一些attr屬性。 attr不依賴於styleable,styleable只是為了方便attr的使用。

Android定義View(二、深入解析定義屬性

目錄: 繼承View,覆蓋構造方法 自定義屬性 重寫onMeasure方法測量寬高 重寫onDraw方法繪製控制元件   接下來幾篇部落格分別深入學習每一個步驟的知識點,第一步就不用多講了,這篇部落格我們看一

Android定義View屬性attr format取值型別

原文連結 1. reference:參考某一資源ID。 (1)屬性定義: <declare-styleable name = "名稱"> <attr name = "background" format = "reference" />

定義view獲取android layout_width等屬性

這裡以獲取layout_width和layout_height為例 1,新建attr檔案 <?xml version="1.0" encoding="utf-8"?> <resour

Android 定義View實現圓形進度條 深入理解onDraw和onMeasure及定義屬性

Android的View類是使用者介面的基礎構件,表示螢幕上的一塊矩形區域,負責這個區域的繪製和事件處理。自定義View的過程主要包括重寫onDraw及onMeasure方法 , 其中onMeasure方法的作用就是計算出自定義View的寬度和高度。這個計算的過

Android 定義view深入剖析

前言 自定義View原理是Android開發者必須瞭解的基礎; 在瞭解自定義View之前,你需要有一定的知識儲備; 本文將全面解析關於自定義View中的所有知識基礎。 目錄 1. View的分類 檢視View主要分為兩類:

Android 定義view(1) --- Attr、Style和Theme詳解

轉載:https://www.jianshu.com/p/dd79220b47dd 概念說明:       Attr:屬性,風格樣式的最小單元;      Style:風格,它是一系列Attr的集合用以定義一個View

Android定義View定義屬性

在Android開發中經常會用到自定義View的情況,而在自定義View時,自定義屬性是必須用到的。 1、新建一個自定義View如CustomView 它的自定義屬性主要是通過declare-styleable標籤為其配置自定義屬性。具體做法是:在res/values/目錄下增加一個reso

HenCoder Android 定義 View 1-7:屬性動畫 Property Animation(進階篇)

這期是 HenCoder 自定義繪製的第 1-7 期:屬性動畫(進階篇) 簡介 上期的內容,對於大多數簡單的屬性動畫場景已經夠用了。這期的內容主要針對兩個方面: 針對特殊型別的屬性來做屬性動畫; 針對複雜的屬性關係來做屬性動畫。 TypeEvaluator

Android 定義View 常用選單的的Table

0909修改 package com.example.myapplication; import android.content.Context; import android.content.res.TypedArray; import android.graphics.

Android定義View的實現方法,帶你一步步深入瞭解View(四)

不知不覺中,帶你一步步深入瞭解View系列的文章已經寫到第四篇了,回顧一下,我們一共學習了LayoutInflater的原理分析、檢視的繪製流程、檢視的狀態及重繪等知識,算是把View中很多重要的知識點都涉及到了。如果你還沒有看過我前面的幾篇文章,建議先去閱讀一下,多瞭解一些

Android定義View的實現方法 帶你一步步深入瞭解View

                不知不覺中,帶你一步步深入瞭解View系列的文章已經寫到第四篇了,回顧一下,我們一共學習了LayoutInflater的原理分析、檢視的繪製流程、檢視的狀態及重繪等知識,算是把View中很多重要的知識點都涉及到了。如果你還沒有看過我前面的幾篇文章,建議先去閱讀一下,多瞭解一些原

Android定義view實現載入、載入失敗、無資料

一、概述 Android中經常在有的app中可以見到“載入中”並不是以彈出對話方塊的形式顯示的,而是佔用整個螢幕,如果載入失敗就會出現載入失敗頁面,點選載入失敗頁面中任意區域,都可以重新載入。今天就和大家一起學習如何通過自定義view的方式實現載入中、載入失敗

android 定義view,在xml引用內部類View

java.lang.ClassCastException: android.view.View cannot be cast to com.voice.VoiceFragment$AnimationView E/AndroidRuntime( 3543): at com.voice.VoiceFragme

從零開始學Android定義View之動畫系列——屬性動畫(3)

屬性動畫對補間動畫進行了很大幅度的改進,之前補間動畫可以做到的屬性動畫也能做到,補間動畫做不到的現在屬性動畫也可以做到了。因此,今天我們就來學習一下屬性動畫的高階用法,看看如何實現一些補間動畫所無法實現的功能。 ValueAnimator的高階用法 補間

android定義view新增XML屬性

1.在value下新建檔案(檔名隨便),把需要的名稱和型別放進去 <?xml version="1.0" encoding="utf-8"?> <resources>

android 定義View(二) 定義屬性和帶滾動的View

自定義View的屬性   在上一章中講了那麼多,這一章開始就進行實戰了。首先來一發自定義View屬性的demo。 自定義View屬性的步驟分為以下3步。 (1) 新建一個attrs.xml檔案,在這個資原始檔中定義我們需要的屬性。 (2)新建一個自定義的

Android定義View獲取定義屬性

首先扯點別的:今晚回家做了一個魚香肉絲,剛學的,出鍋以後,才想起沒有放豆瓣醬,也是沒誰了。不過吃起來還行,吃了三塊煎餅。 今天記錄一下自定義View的建構函式的使用,以及如何獲取自定義屬性。 先看一下自定義View 的建構函式 public class

Android定義View 定義xml屬性設定

Android自定義View實現很簡單 繼承View,重寫建構函式、onDraw,(onMeasure)等函式。 如果自定義的View需要有自定義的屬性,需要在values下建立attrs.xml。在其中定義你的屬性。 在使用到自定義View的xml佈局檔案中需要加

Android定義view屬性動畫一

Android 裡動畫是有一些分類的:動畫可以分為兩類:Animation 和 Transition;其中 Animation 又可以再分為 View Animation 和 Property Animation 兩類: View Animation 是純粹基於 framew