Android Kotlin/Java 动态设置 shape/drawable 等状态效果

简介:       小菜最近遇到一个小需求,程序里面有个别页面,需要动态的调整某个页面的样式,包括一键变灰等效果。      以前页面是用 shape 和 drawable 之类实现的效果。

      小菜最近遇到一个小需求,程序里面有个别页面,需要动态的调整某个页面的样式,包括一键变灰等效果。
      以前页面是用 shape 和 drawable 之类实现的效果。现在需要用 Kotlin/Java 代码实现动态修改。由于小菜技术浅浅,仅整理一下遇到一些坑。


日常应用的样式:

1. 圆角边框

默认 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>

现 Kotlin/Java 方式动态修改边框颜色:

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

Tips: GradientDrawable 对象可设置 shape 边框属性(矩形/椭圆等)、stroke 边框宽度和颜色、cornerRadius 圆角角度、color 填充背景色。

2. 圆角边框填充颜色

默认 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>

现 Kotlin/Java 方式动态修改边框颜色及填充背景色:

var myGrad = tv3!!.getBackground() as GradientDrawable
myGrad.setStroke(1, resources.getColor(R.color.colorPrimary))
myGrad.setColor(resources.getColor(R.color.colorPrimary))
3. 圆角边框填充颜色,点击变更背景色

默认 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>

现 Kotlin/Java 方式动态修改边框颜色填充背景色,点击变更背景色:

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 设置 View 绘制不同状态背景图片,小菜测试中,发现需要设置点击事件或者 Pressed/Focused 状态,小菜认为如果只是设置 StateListDrawable 默认是 normal 样式,不会有点击效果。

4. 圆角边框填充颜色,点击变更背景色及文字颜色

默认 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>

现 Kotlin/Java 方式动态修改边框颜色填充背景色,点击变更背景色及文字颜色:

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 时,新建在 color 资源文件夹下。ColorStateList 对象设置文字点击时不同状态等文字效果。

5. 部分圆角边框填充颜色

默认 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>

现 Kotlin/Java 方式动态修改部分圆角边框:

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 对象中,若设置四个圆角一致时,可设置 cornerRadius 属性;若设置部分圆角时,可设置 cornerRadii 属性,该属性包括 8 个 float 参数 (左上[X_Radius,Y_Radius],右上[X_Radius,Y_Radius],右下[X_Radius,Y_Radius],左下[X_Radius,Y_Radius]) 且只有设置 [X_Radius,Y_Radius] 两个参数时起作用。

6. 图标绘色

默认设置 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" />

现 Kotlin/Java 方式对图标绘色:

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: 用该方法绘制颜色时,建议不要设置图片的 tint 属性。

7. 图片灰度

设置 ColorMatrix 对象的 Saturation 属性:

val matrixpic = ColorMatrix()
matrixpic.setSaturation(0f)//饱和度 0灰色 100过度彩色,50正常
val filter = ColorMatrixColorFilter(matrixpic)
iv1!!.setColorFilter(filter)
xml 布局效果
Kotlin 代码效果
一键灰度

GitHub 实例


      下面是小菜的公众号,欢迎闲来吐槽~


小菜公众号
目录
相关文章
|
5月前
|
XML API Android开发
码农之重学安卓:利用androidx.preference 快速创建一、二级设置菜单(demo)
本文介绍了如何使用androidx.preference库快速创建具有一级和二级菜单的Android设置界面的步骤和示例代码。
154 1
码农之重学安卓:利用androidx.preference 快速创建一、二级设置菜单(demo)
|
3月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
95 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
3月前
|
Java Linux iOS开发
如何设置 Java 的环境变量
设置Java环境变量是使用Java开发工具和运行Java程序的前提。主要步骤包括:安装JDK,配置系统环境变量中的JAVA_HOME、PATH和CLASSPATH,确保命令行可直接调用javac和java命令。
75 6
|
3月前
|
安全 Java Linux
java程序设置开机自启
java程序设置开机自启
166 1
|
4月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
172 1
|
4月前
|
Android开发
Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
本文介绍了 `SpannableString` 在 Android 开发中的强大功能,包括如何在单个字符串中应用多种样式,如颜色、字体大小、风格等,并提供了详细代码示例,展示如何设置文本颜色、添加点击事件等,助你实现丰富文本效果。
328 3
|
5月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
5月前
|
Java 调度 Android开发
Android经典实战之Kotlin的delay函数和Java中的Thread.sleep有什么不同?
本文介绍了 Kotlin 中的 `delay` 函数与 Java 中 `Thread.sleep` 方法的区别。两者均可暂停代码执行,但 `delay` 适用于协程,非阻塞且高效;`Thread.sleep` 则阻塞当前线程。理解这些差异有助于提高程序效率与可读性。
89 1
|
4月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
163 0
|
5月前
|
IDE Java Linux
探索安卓开发:从基础到进阶的旅程Java中的异常处理:从基础到高级
【8月更文挑战第30天】在这个数字时代,移动应用已经成为我们日常生活中不可或缺的一部分。安卓系统由于其开放性和灵活性,成为了开发者的首选平台之一。本文将带领读者踏上一段从零开始的安卓开发之旅,通过深入浅出的方式介绍安卓开发的基础知识、核心概念以及进阶技巧。我们将一起构建一个简单的安卓应用,并探讨如何优化代码以提高性能和应用的用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供宝贵的知识和启发。