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 实例


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


小菜公众号
目录
相关文章
|
4天前
|
XML 存储 编解码
android 目录结构中 drawable(hdpi,ldpi,mdpi) 的区别
android 目录结构中 drawable(hdpi,ldpi,mdpi) 的区别
10 1
|
1天前
|
安全 Java 数据安全/隐私保护
Java一分钟之-Java反射机制:动态操作类与对象
【5月更文挑战第12天】本文介绍了Java反射机制的基本用法,包括获取Class对象、创建对象、访问字段和调用方法。同时,讨论了常见的问题和易错点,如忽略访问权限检查、未捕获异常以及性能损耗,并提供了相应的避免策略。理解反射的工作原理和合理使用有助于提升代码灵活性,但需注意其带来的安全风险和性能影响。
15 4
|
1天前
|
移动开发 监控 Android开发
构建高效Android应用:Kotlin协程的实践与优化
【5月更文挑战第12天】 在移动开发领域,性能与响应性是衡量一个应用程序优劣的关键指标。特别是在Android平台上,由于设备的多样性和系统资源的限制,开发者需要精心编写代码以确保应用流畅运行。近年来,Kotlin语言因其简洁性和功能性而广受欢迎,尤其是其协程特性,为异步编程提供了强大而轻量级的解决方案。本文将深入探讨如何在Android应用中使用Kotlin协程来提升性能,以及如何针对实际问题进行优化,确保应用的高效稳定执行。
|
2天前
|
移动开发 API Android开发
构建高效Android应用:Kotlin协程的实践指南
【5月更文挑战第11天】 在移动开发领域,性能优化和资源管理是至关重要的。特别地,对于Android开发者来说,合理利用Kotlin协程可以极大地改善应用的响应性和稳定性。本文将深入探讨Kotlin协程在Android中的实际应用,包括它们如何简化异步编程模型、提高UI线程的响应性,以及减少内存消耗。我们将通过具体案例分析,了解如何在实际项目中有效地使用协程,从而帮助开发者构建更加高效的Android应用程序。
|
4天前
|
Java API 开发工具
java与Android开发入门指南
java与Android开发入门指南
11 0
|
5天前
|
安全 Java Android开发
构建高效Android应用:采用Kotlin进行内存优化的策略
【5月更文挑战第8天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,合理管理内存资源是确保应用流畅运行的关键因素之一。近年来,Kotlin作为官方推荐的开发语言,以其简洁、安全和互操作性的特点受到开发者青睐。本文将深入探讨利用Kotlin语言特性,通过具体策略对Android应用的内存使用进行优化,旨在帮助开发者提高应用性能,减少内存消耗,避免常见的内存泄漏问题。
8 0
|
6天前
|
Android开发 Kotlin
Kotlin开发Android之基础问题记录
Kotlin开发Android之基础问题记录
16 1
|
6天前
|
移动开发 数据库 Android开发
构建高效Android应用:Kotlin协程的全面应用
【5月更文挑战第7天】 在移动开发领域,性能优化与流畅的用户体验是至关重要的。随着Kotlin语言的流行,其并发神器——协程,已成为提升Android应用性能的重要工具。本文将深入探讨如何在Android项目中利用Kotlin协程进行异步编程、网络请求和数据库操作,以及如何通过协程简化代码结构,增强应用的响应性和稳定性。我们的目标是为开发者提供一套实用的协程使用模式和最佳实践,以便构建更加高效的Android应用。
23 3
|
6天前
|
移动开发 Java Android开发
Android应用开发:Kotlin语言的优势与实践
【5月更文挑战第7天】 在移动开发的世界中,Android平台的Kotlin语言以其高效、简洁的语法和强大的功能吸引了众多开发者。本文将深入探讨Kotlin语言的核心优势,并通过实际案例展示如何在Android应用开发中有效地运用这一现代编程语言。我们将从语言特性出发,逐步分析其在提升开发效率、改善代码质量以及增强应用性能方面的具体表现,为读者提供一个全面而细致的Kotlin应用开发指南。
|
6天前
|
移动开发 数据库 Android开发
构建高效Android应用:Kotlin与协程的完美结合
【5月更文挑战第7天】 在移动开发领域,性能优化和资源管理始终是核心议题。随着Kotlin语言的普及,其提供的协程特性为Android开发者带来了异步编程的新范式。本文将深入探讨如何通过Kotlin协程来优化Android应用的性能,实现流畅的用户体验,并减少资源消耗。我们将分析协程的核心概念,并通过实际案例演示其在Android开发中的应用场景和优势。