Android 自定義 Drawable
在 Android
中,說到 Drawable
,第一個想到的時候?是不是 drawable 裡面的 shape 或者 selector 或者就是那麼一個個圖示?
Drawable
是一個抽象類,描述的是一些可以被畫出來的東西,其實 View
也是畫東西出來嘛,Drawable
和 View
的最明顯區別就是它只能畫東西,沒法接收事件響應互動。
現在有如下的需求:
![2244299-57a5f304b34bc8f4.gif](https://i.iter01.com/images/a0f4c8ae1be4841d8713e6885632e27b78c411886c940a7d1088aab1f5d8bf39.gif)
簡單的說就是需要畫三種狀態(選中,未選中,不可選)的背景,三種狀態,這個好說,如果使用 xml 的話,就是上面說的 selector,直接使用物件的話就是 StateListDrawable
,狀態的話,就是state_enabled
,state_checked
就可以啦。等等,不是三個狀態嗎?不是還有一個 unable 的狀態嗎?這個等下看程式碼吧。
![2244299-dbb0f88a55b6545a.png](https://i.iter01.com/images/d0fe2ea96d35de192e4284f19dc781e70dbe25321b12e372d34b05ce0d112678.png)
接下來,就需要來畫出這三種狀態的 Drawable
了,其實很簡單的,未選中和不可選都是畫一個矩形的邊框就好了,選中也就是在矩形邊框的基礎上再加上左上方一個三角形就好了,至於畫三角形,使用 Path
就可以搞定的。這個就是基本思路了。
![2244299-a667454c0f3fcfad.png](https://i.iter01.com/images/944305a1a8371d75b1d3a83fe527b1f66195414dc495df3186b491ef727b0261.png)
自定義一個 Drawable
,抽象類嘛,必須實現四個方法,draw()
就不用講了,setAlpha()
就是這是設定 alpha 咯,setColorFilter()
,就是設定顏色過濾了,getOpacity()
獲取不透明度,這個只能返回指定的半透明、透明、未指定幾種情況。其中兩個set的方法是用來讓我們設定的。綜合起來的話,我們這裡根本就不用關心這個透明度或者 colorfilter 的問題,所以其他三個方法直接空處理或者返回預設值就好了。
接下來差不多就可以擼程式碼了。
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(mainColor);
mPaint.setStrokeWidth(6);
//設定畫虛線,如果之後不再使用虛線,呼叫paint.setPathEffect(null);
pathPaint = new Paint(mPaint);
pathPaint.setStyle(Paint.Style.FILL);
mArrow = new Path();
先定義一個 Paint
,還有一個 Path
,用來畫那個三角形。這裡遇到第一個問題,strokeWidth 不能寫死畫素值啊,但是 Drawable
裡面似乎沒有Context
的引用,所以還沒法轉 dp 了,所以只有在初始化 Drawable
的時候傳一個 Context
進來吧!另外,還有一個問題呢,這個 Drawable
的寬高怎麼確定?我們畫的那個三角形肯定是需要跟著高度呈一定的比例咯,這裡就涉及到 onBoundsChange()
的方法了。
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect = bounds;
int value = (int) (bounds.height() * 0.1f);
mArrow.reset();
mArrow.moveTo(0, 0);
value = (int) (value * 1.5f);
mArrow.lineTo(value, 0);
mArrow.lineTo(0, value);
mArrow.close();
invalidateSelf();
}
這兩個問題解決了,那麼最後就是在 draw()
的方法中畫出來了。
switch (currentState) {
case STATE_CHECKED://選中狀態
mPaint.setColor(checkedColor);
pathPaint.setColor(checkedColor);
canvas.drawRect(mRect, mPaint);
canvas.drawPath(mArrow, pathPaint);
break;
case STATE_UNABLE://不可用狀態 畫虛線
mPaint.setColor(borderColor);
PathEffect effects = new DashPathEffect(new float[]{10, 10, 10, 10}, 1);
mPaint.setPathEffect(effects);
canvas.drawRect(mRect, mPaint);
break;
case STATE_NORMAL://正常狀態
mPaint.setColor(borderColor);
canvas.drawRect(mRect, mPaint);
break;
}
好了,到這裡最基本的 Drawable
就搞定了,接下來還要搞定這個狀態的改變。
接下來實現一個 StateListDrawable
,將相關的狀態和上面的 Drawable
繫結起來就好了,其他的就不用我們操心了。
addState(new int[]{android.R.attr.state_checked}, new CategoryDrawable(CategoryDrawable.STATE_CHECKED, mColor, showInner));
//unable 就是這樣定義的
addState(new int[]{-android.R.attr.state_enabled}, new CategoryDrawable(CategoryDrawable.STATE_UNABLE, mColor, showInner));
addState(new int[]{}, new CategoryDrawable(CategoryDrawable.STATE_NORMAL, mColor, showInner));
最後,就是給 View
新增我們製作好的 Drawable
了,這裡需要支援Checkable
的 TextView
,那麼必須就是 CheckedTextView
了。
下載
相關文章
- Android: Bitmap/Canvas/DrawableAndroidCanvas
- android自定義view(自定義數字鍵盤)AndroidView
- Android自定義View整合AndroidView
- Android自定義遮罩層Android遮罩
- 自定義Android鍵盤Android
- Android自定義OnTouch事件Android事件
- Android 自定義UI元件AndroidUI元件
- android 自定義鍵盤Android
- Android技能樹 — Drawable小結Android
- Android 自定義View:深入理解自定義屬性(七)AndroidView
- 重拾Android自定義ViewAndroidView
- Android自定義View:ViewGroup(三)AndroidView
- Android自定義View:View(二)AndroidView
- Android 自定義 View 之 LeavesLoadingAndroidView
- Android自定義拍照實現Android
- Android 自定義Toast及BUGAndroidAST
- Android 的各種 Drawable 詳解Android
- Android-Drawable setColorFilter方法踩坑AndroidFilter
- Android自定義View之分貝儀AndroidView
- Android自定義View之捲尺AndroidView
- Android 自定義優雅的BezierSeekBarAndroid
- 自定義Android Studio程式碼模板Android
- Android自定義View注意事項AndroidView
- Android自定義View-卷軸AndroidView
- Android自定義View 水波氣泡AndroidView
- Android 自定義View 點贊效果AndroidView
- Android 自定義View基礎(一)AndroidView
- android自定義View——座標系AndroidView
- Android自定義數字鍵盤Android
- Android技術分享| 自定義LayoutManagerAndroid
- Android 端如何新增自定義表情Android
- Android 好用的自定義元件、框架Android元件框架
- Android自定義字型--自定義TextView(可擴充套件不同ttf字Android自定義字型TextView套件
- [Android] Folivora,在layout中直接建立drawableAndroid
- Android自定義滑動刻度尺Android
- Android自定義View播放Gif動畫AndroidView動畫
- Android 自定義構建型別 BuildTypeAndroid型別UI
- Android 自定義 View 實戰之 PuzzleViewAndroidView
- Android 自定義 View 之入門篇AndroidView