Android Kotlin/Java 動(dòng)態(tài)設(shè)置 shape/drawable 等狀態(tài)效果

??????小菜最近遇到一個(gè)小需求,程序里面有個(gè)別頁(yè)面,需要?jiǎng)討B(tài)的調(diào)整某個(gè)頁(yè)面的樣式,包括一鍵變灰等效果。
??????以前頁(yè)面是用 shape 和 drawable 之類(lèi)實(shí)現(xiàn)的效果。現(xiàn)在需要用 Kotlin/Java 代碼實(shí)現(xiàn)動(dòng)態(tài)修改。由于小菜技術(shù)淺淺,僅整理一下遇到一些坑。


日常應(yīng)用的樣式:

1. 圓角邊框

默認(rèn) shape.xml 方式:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="0.5dp"
        android:color="@color/colorAccent" />
    <corners android:radius="15dp" />
</shape>

現(xiàn) Kotlin/Java 方式動(dòng)態(tài)修改邊框顏色:

var myGrad = tv2!!.getBackground() as GradientDrawable
myGrad.setStroke(1, resources.getColor(R.color.colorPrimary))

Tips: GradientDrawable 對(duì)象可設(shè)置 shape 邊框?qū)傩?矩形/橢圓等)、stroke 邊框?qū)挾群皖伾?、cornerRadius 圓角角度、color 填充背景色。

2. 圓角邊框填充顏色

默認(rèn) shape.xml 方式:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorAccent" />
    <stroke
        android:width="0.5dp"
        android:color="@color/colorAccent" />
    <corners android:radius="15dp" />
</shape>

現(xiàn) Kotlin/Java 方式動(dòng)態(tài)修改邊框顏色及填充背景色:

var myGrad = tv3!!.getBackground() as GradientDrawable
myGrad.setStroke(1, resources.getColor(R.color.colorPrimary))
myGrad.setColor(resources.getColor(R.color.colorPrimary))
3. 圓角邊框填充顏色,點(diǎn)擊變更背景色

默認(rèn) shape.xml 方式:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/drawable_test1" android:state_pressed="true" />
    <item android:drawable="@drawable/drawable_test2" android:state_focused="false" android:state_pressed="false" />
    <item android:drawable="@drawable/drawable_test1" android:state_focused="true" />
    <item android:drawable="@drawable/drawable_test2" android:state_focused="false" />
</selector>

現(xiàn) Kotlin/Java 方式動(dòng)態(tài)修改邊框顏色填充背景色,點(diǎn)擊變更背景色:

var myGrad1 = GradientDrawable()
myGrad1.setStroke(1, resources.getColor(R.color.colorPrimary))
myGrad1.cornerRadius = 80.0f
myGrad1.setColor(resources.getColor(R.color.colorPrimary))
var myGrad2 = GradientDrawable()
myGrad2.setStroke(1, resources.getColor(R.color.colorPrimary))
myGrad2.cornerRadius = 80.0f
myGrad2.setColor(resources.getColor(R.color.white))
tv4!!.background = BitmapUtil.addStateDrawable1(context, myGrad3, myGrad4, myGrad4, myGrad4)
public static StateListDrawable addStateDrawable1(Context context, Drawable idNormal, Drawable idPressed, Drawable idFocused, Drawable idUnable) {
    StateListDrawable bg = new StateListDrawable();
    Drawable normal = idNormal;
    Drawable pressed = idPressed;
    Drawable focused = idFocused;
    Drawable unable = idUnable;
    // View.PRESSED_ENABLED_STATE_SET
    bg.addState(new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled }, pressed);
    // View.ENABLED_FOCUSED_STATE_SET
    bg.addState(new int[] { android.R.attr.state_enabled, android.R.attr.state_focused }, focused);
    // View.ENABLED_STATE_SET
    bg.addState(new int[] { android.R.attr.state_enabled }, normal);
    // View.FOCUSED_STATE_SET
    bg.addState(new int[] { android.R.attr.state_focused }, focused);
    // View.WINDOW_FOCUSED_STATE_SET
    bg.addState(new int[] { android.R.attr.state_window_focused }, unable);
    // View.EMPTY_STATE_SET
    bg.addState(new int[] {}, normal);
    return bg;
}

Tips: StateListDrawable 設(shè)置 View 繪制不同狀態(tài)背景圖片,小菜測(cè)試中,發(fā)現(xiàn)需要設(shè)置點(diǎn)擊事件或者 Pressed/Focused 狀態(tài),小菜認(rèn)為如果只是設(shè)置 StateListDrawable 默認(rèn)是 normal 樣式,不會(huì)有點(diǎn)擊效果。

4. 圓角邊框填充顏色,點(diǎn)擊變更背景色及文字顏色

默認(rèn) color.xml 方式:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_selected="true" />
    <item android:color="@color/colorAccent" android:state_focused="true" />
    <item android:color="@color/colorAccent" android:state_pressed="true" />
    <item android:color="@color/white" />
</selector>

現(xiàn) Kotlin/Java 方式動(dòng)態(tài)修改邊框顏色填充背景色,點(diǎn)擊變更背景色及文字顏色:

tv5!!.setTextColor(BitmapUtil.createColorStateList(getResources().getColor(R.color.white), getResources().getColor(R.color.colorPrimary),
                getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorPrimary)));
public static ColorStateList createColorStateList(int normal, int pressed, int focused, int unable) {
    int[] colors = new int[] { pressed, focused, normal, focused, unable, normal };
    int[][] states = new int[6][];
    states[0] = new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled };
    states[1] = new int[] { android.R.attr.state_enabled, android.R.attr.state_focused };
    states[2] = new int[] { android.R.attr.state_enabled };
    states[3] = new int[] { android.R.attr.state_focused };
    states[4] = new int[] { android.R.attr.state_window_focused };
    states[5] = new int[] {};
    ColorStateList colorList = new ColorStateList(states, colors);
    return colorList;
}

Tips: 小菜建議在編輯 color.xml 時(shí),新建在 color 資源文件夾下。ColorStateList 對(duì)象設(shè)置文字點(diǎn)擊時(shí)不同狀態(tài)等文字效果。

5. 部分圓角邊框填充顏色

默認(rèn) shape.xml 方式:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorAccent" />
    <stroke
        android:width="0.5dp"
        android:color="@color/colorAccent" />
    <corners
        android:bottomLeftRadius="15dp"
        android:topLeftRadius="15dp" />
</shape>

現(xiàn) Kotlin/Java 方式動(dòng)態(tài)修改部分圓角邊框:

var myGrad = GradientDrawable()
var farr = floatArrayOf(80.0f, 80.0f, 0.0f, 0.0f, 0.0f, 0.0f, 80.0f, 80.0f)
myGrad.cornerRadii = farr
myGrad.setStroke(1, resources.getColor(R.color.colorPrimary))
myGrad.setColor(resources.getColor(R.color.colorPrimary))
tv6!!.background = myGrad

Tips: GradientDrawable 對(duì)象中,若設(shè)置四個(gè)圓角一致時(shí),可設(shè)置 cornerRadius 屬性;若設(shè)置部分圓角時(shí),可設(shè)置 cornerRadii 屬性,該屬性包括 8 個(gè) float 參數(shù) (左上[X_Radius,Y_Radius],右上[X_Radius,Y_Radius],右下[X_Radius,Y_Radius],左下[X_Radius,Y_Radius]) 且只有設(shè)置 [X_Radius,Y_Radius] 兩個(gè)參數(shù)時(shí)起作用。

6. 圖標(biāo)繪色

默認(rèn)設(shè)置 tint 屬性:

<ImageView
    android:id="@+id/drawable_iv3"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_marginTop="20dp"
    android:src="@mipmap/icon_zan"
    android:tint="@color/colorAccent" />

現(xiàn) Kotlin/Java 方式對(duì)圖標(biāo)繪色:

var plabit = BitmapUtil.drawableToBitmap3(resources.getDrawable(R.mipmap.icon_zan))
plabit = BitmapUtil.tintBitmap(plabit, resources.getColor(R.color.inactive_bottom_navigation))
iv2!!.setImageDrawable(BitmapDrawable(plabit))
public static Bitmap drawableToBitmap3(Drawable drawable) {
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                drawable.getIntrinsicHeight(),
                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                        : Bitmap.Config.RGB_565);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    drawable.draw(canvas);
    return bitmap;
}

Tips: 用該方法繪制顏色時(shí),建議不要設(shè)置圖片的 tint 屬性。

7. 圖片灰度

設(shè)置 ColorMatrix 對(duì)象的 Saturation 屬性:

val matrixpic = ColorMatrix()
matrixpic.setSaturation(0f)//飽和度 0灰色 100過(guò)度彩色,50正常
val filter = ColorMatrixColorFilter(matrixpic)
iv1!!.setColorFilter(filter)
xml 布局效果
Kotlin 代碼效果
一鍵灰度

GitHub 實(shí)例


來(lái)源: 阿策小和尚

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容