前言
本篇主要記錄的是自定義 View 和自定義屬性的流程
正文
一溜在、自定義 View 的步驟
第一步,創(chuàng)建一個類繼承自需要的 View 或 ViewGroup,重寫構(gòu)造方法
第二步昆雀,重寫 onMeasure() 方法辱志,測量控件的大小,并指定大小狞膘,指定大小的方法為:
setMeasuredDimension(200,100);
第三步荸频,重寫 onLayout() 方法,指定該控件在父控件中的位置客冈,但是此方法是系統(tǒng)調(diào)用的,告訴我們我們的控件在父控件什么位置稳强,一般在自定義 ViewGroup 中用的比較多场仲。
第四步,重寫 onDraw() 方法退疫,繪制自己需要的圖案渠缕,但是大部分的自定義控件都是繪制圖片
第五步,重寫 onTouchEvent() 方法褒繁,處理觸摸事件亦鳞,在這一步容易出現(xiàn)點擊事件和滑動事件的沖突,原因是因為棒坏,系統(tǒng)默認只要發(fā)生了 up 事件燕差,就會執(zhí)行點擊事件的邏輯。處理完事件之后坝冕,一般需要重新繪制 View徒探,方法如下
invalidate() //刷新 View ,會重新調(diào)用 onDraw() 方法喂窟,在主線程中調(diào)用
postInvalidate() //與上邊方法的區(qū)別在于测暗,在子線程中調(diào)用
- onSizeChanged() 方法
/**
* 在view第一次被指定了大小值、或者view的大小發(fā)生改變時會被調(diào)用磨澡。
* 所以一般用來計算一些位置和與view的size有關(guān)的值碗啄。
*
* @param w 最終的寬度
* @param h 最終的高度
* @param oldw 上次的寬度
* @param oldh 上次的高度
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
二、自定義屬性
作用: 為自定義控件添加屬性稳摄,增強其復(fù)用性稚字,比如說羡藐,我寫一個自定義控件的背景是固定死的驱入,想要換顏色的話就通過自定義屬性來設(shè)置。
步驟:
首先先思考下捧存,系統(tǒng)中的控件的屬性是怎么生效的弃锐, 我們仿照系統(tǒng)的方式來來設(shè)置即可袄友,而系統(tǒng)控件的屬性在
E:\androidStudioSDK\platforms\android-14\data\res\values 目錄下的 attrs.xml 文件中比如說,我們現(xiàn)在的需求是霹菊,給一個自定義的按鈕設(shè)置一個背景屬性剧蚣,使其能夠隨便切換背景
2.1 第一步支竹,聲明屬性,即:在 values 文件夾下創(chuàng)建一個 attrs.xml 文件鸠按,名稱可以隨意礼搁,不一定非得是 attrs ,然后編輯該文件
- 聲明一個屬性集合目尖,名字一般跟自定義控件的名字一致
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--聲明一個屬性集合馒吴,名字一般跟自定義控件的名字一致,這個名字在后邊會用到-->
<declare-styleable name="Mybtn">
</declare-styleable>
</resources>
- 聲明背景屬性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--聲明一個屬性集合瑟曲,名字一般跟自定義控件的名字一致-->
<declare-styleable name="MyView">
<!--聲明背景屬性饮戳,format 表示類型為引用圖片類型-->
<attr name="btnBg" format="reference|color" />
</declare-styleable>
</resources>
2.2 第二步,在布局文件中使用屬性
- 聲明一個命名空間洞拨,類似于系統(tǒng)中的控件扯罐,如:
xmlns:android="http://schemas.android.com/apk/res/android"
其中 xmlns 表示命名空間的意思,android 只是一個名字烦衣,只不過這個名字被系統(tǒng)定義好了
而我們聲明的時候歹河,也類似于這種格式:
xmlns:zhangsan="http://schemas.android.com/apk/res-auto"
其中,zhangsan 是我們隨意命名的花吟,eclipse 中是把最后的 android 換成包名秸歧,而 AndroidStudio 中是換成 res-auto
- 在自定義控件中使用自定義屬性
zhangsan:btnBg="@mipmap/ic_launcher"
其中,zahngsan 是我們命名空間的名字衅澈,btnBg 是我們聲明的屬性寥茫,跟系統(tǒng)的 android:XXX 是一樣的
2.3 在自定義控件中獲得布局文件中聲明的屬性,使其生效矾麻!
- 主要操作的是自定義控件中兩個屬性的構(gòu)造方法:
/**
*
* @param context
* @param attrs 在布局中聲明的所有屬性
*/
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
- 具體操作如下:
/**
*
* @param context
* @param attrs 在布局中聲明的所有屬性
*/
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
// R.styleable.MyView 就是我們在 attrs.xml 文件中聲明的屬性集合
//根據(jù)基本的屬性集合纱耻,獲得一個各個類型的數(shù)組
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView);
// R.styleable.MyView_btnBg 是由系統(tǒng)生成的 屬性集合_屬性名稱
//獲取到的就是我們設(shè)置的圖片資源
BitmapDrawable bitmapDrawable = (BitmapDrawable) typedArray.getDrawable(R.styleable.MyView_btnBg);
//將之前的圖片替換成設(shè)置的即可,在 onDraw 方法中通過 drawXXX 方法繪畫出來
Bitmap bitmap = bitmapDrawable.getBitmap();
}