Android 着色器 Tint 研究

Android之tint图片着色器 1、爆照 上面是原图,下面是点击效果。 2、介绍 设置着色模式用的。这个模式共有6种,分别为: multiply screen src_in(默认) src_over src_atop add android:tint 属性可以改变图片颜色 3 源代码 colors.xml <?xml version="1.0" encoding="utf-8"?> <resources> &... 阅读详情
原文出处:http://www.cnblogs.com/punkisnotdead/p/5139372.html

Tint 这个东西 主要用来减少apk体积的,比如说我现在有一个textview,他的背景图 有两种,一种是当获得焦点时显示的a图,另一种是 失去焦点时显示的b图。

相信大家开发的时候 这种需求做过很多次了,我们一般都会发现 这种a图和b图 除了颜色不一样,其他都是一样的,但是我们做的时候呢,通常是找ui要了两张图。

如果要适配分辨率的话 很有可能图片会更多,而且在切换的时候 因为是重新加载一次bitmap 效率也会下降很多。所以谷歌就给了一套解决方案 这个就是tint了。

他的目的就是当你发现有这种需求的时候,只需要 放一张图 在apk里即可,当你需要改变背景图的颜色的时候 就用Tint即可!

下面就来简单说一下,tint的使用 以及需要注意的地方。

 

首先 我们定义一个简单的布局文件:

我们发现这2个imageview 都是引用的同样一个drawable资源,并且 在studio这个xml编辑界面里面 我们很明显的 能看出来 这个图片的颜色是黑色的 对吧!

那 现在 我们想改一下,想把iv1 这个imageview的 背景色 改成绿色的! 我们想当然的 当然会这么写:

1         iv1 = (ImageView) this.findViewById(R.id.iv1);
2         iv2 = (ImageView) this.findViewById(R.id.iv2);
3 
4         final Drawable originBitmapDrawable = getResources().getDrawable(R.drawable.ic_account_circle_black_18dp);
5         iv1.setImageDrawable(tintDrawable(originBitmapDrawable, ColorStateList.valueOf(Color.GREEN)));

应该很好理解对吧,代码就不解释了。但是我们运行以后发现:

卧槽 怎么2个都变绿色了!

回顾一下 我们的代码 我们应该能明白 2个imageview 都是引用的同样的一个drawable,要知道 既然是一个drawable,那系统肯定为了优化资源 把这2个drawable 在内存里的拷贝弄成了一份!

还记得 我们以前讲的bitmap优化那篇么?http://www.cnblogs.com/punkisnotdead/p/4881771.html  和这个里面的inBitmap 属性有异曲同工之妙,如果还不理解 你看下面的图就理解了:

所以才会造成上面的情况。你修改了共同变量,所以2个图就都被影响了。

解决方法 其实也很简单:

1         final Drawable originBitmapDrawable = getResources().getDrawable(R.drawable.ic_account_circle_black_18dp).mutate();

修改以后 我们再看:

你看这么做就一切正常了。

那有人就要问了,卧槽 你这么做 不是把谷歌给我们做好的图片内存优化方案给损坏了么,其实这种担心是多余的,这个http://android-developers.blogspot.hk/2009/05/drawable-mutations.html

这个地址会告诉你 其实我们做 只是把单独的受到影响的那部分 内存给单独拿出来了,其他没受到影响的还是共享的数据!换句话说 我们内存里 会另外存放的就是一些纯的标志位 之类的 类似于状态值这种东西。

大部分的内存还是公用的!

 

然后接着来,我们看下一个例子 关于editext的。

 

你看这个edittext 的颜色是这样的。那现在我们来修改一下 这个edittext的背景色

1         et1 = (EditText) this.findViewById(R.id.et);
2         final Drawable originBitmapDrawable = et1.getBackground();
3         et1.setBackgroundDrawable(tintDrawable(originBitmapDrawable, ColorStateList.valueOf(Color.GREEN)));

 

背景色是修改成功了 但是这个光标的颜色 还没变 非常不协调, 有人又要说了 我们可以用:

这个xml 属性来修改呀,当然了这个方法确实是可以的 但是你想 你这么做的话 又要增加资源文件了,不是与我们的tint 背道而驰了么?

所以 这个地方 我们就要想办法 突破一下。其实很多人都能想到方法了,对于android 没有 提供给我们的api 比如那些private 函数,

我们通常都是通过反射的方法 去调用的。 这里也是一样,稍微想一下 我们就能明白, 这个地方 我们就先通过反射来获取到这个cursorDrawable

然后给他着色,然后在反射调用方法 给他set进去不就行了么?

首先我们都知道 editext 实际上就是textview,所以我们看一下textview 的源码 找找看 这个属性到底叫啥名字。经过一番努力发现 在这:

1  // Although these fields are specific to editable text, they are not added to Editor because
2     // they are defined by the TextView's style and are theme-dependent.
3     int mCursorDrawableRes;

并且我们要看下editor的源码 这是和edittext息息相关的:

/**
     * EditText specific data, created on demand when one of the Editor fields is used.
     * See {@link #createEditorIfNeeded()}.
     */
    private Editor mEditor;
1 //注意这段代码属于editor   
2  final Drawable[] mCursorDrawable = new Drawable[2];

有了这段代码 我们就知道 剩下反射的代码怎么写了。

复制代码
 1 //参数就是要反射修改光标的edittext对象
 2     private void invokeEditTextCallCursorDrawable(EditText et) {
 3         try {
 4             Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
 5             // 看源码知道 这个变量不是public的 所以要设置下这个可访问属性
 6             fCursorDrawableRes.setAccessible(true);
 7             //取得 editext对象里的mCursorDrawableRes 属性的值 看源码知道这是一个int值
 8             int mCursorDrawableRes = fCursorDrawableRes.getInt(et);
 9             //下面的代码 是通过获取mEditor对象 然后再通过拿到的mEditor对象来获取最终我们的mCursorDrawable这个光标的drawable
10             Field fEditor = TextView.class.getDeclaredField("mEditor");
11             fEditor.setAccessible(true);
12             Object editor = fEditor.get(et);
13             Class<?> clazz = editor.getClass();
14             Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
15             fCursorDrawable.setAccessible(true);
16             if (mCursorDrawableRes <= 0) {
17                 return;
18             }
19             //到这里 我们终于拿到了默认主题下 edittext的光标的那个小图标的drawable
20             Drawable cursorDrawable = et.getContext().getResources().getDrawable(mCursorDrawableRes);
21             if (cursorDrawable == null) {
22                 return;
23             }
24             //既然都拿到了这个drawble 那就修改他。
25             Drawable tintDrawable = tintDrawable(cursorDrawable, ColorStateList.valueOf(Color.GREEN));
26             //前面贴出的mCursorDrawable源码 可以知道 这是一个二维数组。所以我们要构造出一个全新的二维数组
27             Drawable[] drawables = new Drawable[]{tintDrawable, tintDrawable};
28             //然后再通过反射 把这个二维数组的值 放到editor里面 即可!
29             fCursorDrawable.set(editor, drawables);
30         } catch (NoSuchFieldException e) {
31             e.printStackTrace();
32         } catch (IllegalAccessException e) {
33             e.printStackTrace();
34         }
35 
36     }
复制代码

最后调用这个方法以后看一下效果:

很完美 对吧~~

最后tintDrawable这个方法是用来向下兼容用的。你如果不考虑向下兼容的问题 用系统自带的方法 就可以了,这里就不做过多介绍了。

1  public static Drawable tintDrawable(Drawable drawable, ColorStateList colors) {
2         final Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
3         DrawableCompat.setTintList(wrappedDrawable, colors);
4         return wrappedDrawable;
5     }

当然你也可以用http://andraskindler.com/blog/2015/tinting_drawables/ 这个文章里的方法来做向下兼容:

复制代码
 1 public final class TintedBitmapDrawable extends BitmapDrawable {
 2   private int tint;
 3   private int alpha;
 4 
 5   public TintedBitmapDrawable(final Resources res, final Bitmap bitmap, final int tint) {
 6     super(res, bitmap);
 7     this.tint = tint;
 8     this.alpha = Color.alpha(tint);
 9   }
10 
11   public TintedBitmapDrawable(final Resources res, final int resId, final int tint) {
12     super(res, BitmapFactory.decodeResource(res, resId));
13     this.tint = tint;
14     this.alpha = Color.alpha(tint);
15   }
16 
17   public void setTint(final int tint) {
18     this.tint = tint;
19     this.alpha = Color.alpha(tint);
20   }
21 
22   @Override public void draw(final Canvas canvas) {
23     final Paint paint = getPaint();
24     if (paint.getColorFilter() == null) {
25       paint.setColorFilter(new LightingColorFilter(tint, 0));
26       paint.setAlpha(alpha);
27     }
28     super.draw(canvas);
29   }
30 }
复制代码

 



人工智能——框架表示法 1975年美国明斯基在“A framework for representing knowledge”提出了框架理论。 1. 框架及框架的一般表示形式 框架:一种描述对象属性的数据结构。 框架的一般表示形式 <框架名> 槽名1: 侧面名1:值1,值2…,值p1 侧面名2:值1,值2…,值p2 侧面名2:值1,值2…,值pm1 槽名2: 侧面名... 阅读详情

相关推荐

ROS2_Moveit2_Ur5e_Grasp项目详解(二):核心模块功能解析

本文深入解析了ROS2_Moveit2_Ur5e_Grasp项目的核心模块功能。重点阐述了OctoMap建图模块如何为机械臂提供实时三维环境感知,并详细介绍了Robotiq夹爪与MoveIt2的集成控制、UR5e的运动规划策略,以及视觉模块如何协同工作,最终实现从目标检测到动态抓取的完整闭环。

weixin_29254029的博客 109

Android 图片着色 Tint 详解2—xml设置、selector

上篇文章介绍了给drawable设置tint 以达到颜色变化效果,这篇介绍下通过xml设置tint、代码设置tint以及如何设置tint selector。在xml中设置tint可以利用 android:tint 以及 android:tintMode 属性设置布局中的着色颜色和模式。而对背景进行着色可以通过设置 android:backgroundTint 属性,但是需要注意几点: 在布局中设置a

JM_beizi的专栏 1万+

Latex小白也能搞定!5分钟教你用Overleaf打造个性化简历(附免费模板)

本文为LaTeX新手提供了一份快速上手指南,教你如何在5分钟内使用Overleaf在线平台和现成模板,轻松打造专业且个性化的简历。文章详细介绍了从选择模板、替换个人信息到进行颜色、图标等个性化调整的完整流程,让你无需深入学习LaTeX语法,即可高效制作出排版精美、脱颖而出的求职简历。

2a4s6d8f0g的博客 682

TextView 等 设置颜色和显示颜色不一致问题

这两天优化项目中,踩了个坑,记录一下,防止下次碰上了,解决不了, 这个坑太小了,顺便说一下场景吧,也算是共享一下自家的一个小方法, 插播:写完了 才发现坑还没说。。 @Override protected void setTitleTextColor(int color) { String currentColor = "#" + Integer.toHex...

sunan_n_的博客 1691

Android加密开发实战:Spongy Castle集成与国密算法应用指南

在移动应用开发中,数据加密是保障用户隐私和信息安全的基石。其原理基于密码学算法,通过对数据进行编码转换,确保即使数据被截获也无法被未授权方解读。这项技术的核心价值在于为敏感信息提供机密性、完整性和身份验证,广泛应用于用户登录、本地存储、网络通信等场景。对于Android开发者而言,系统自带的加密功能有时无法满足需求,特别是涉及国密算法或更丰富算法套件时。本文聚焦于Spongy Castle这一专为Android定制的加密库,它有效解决了与系统内置Bouncy Castle的兼容性问题,并提供了对SM4等国密

weixin_27722377的博客 307

RT-Thread代码启动过程——以及 $Sub$ $main 与 $Super$ $main

我们找到系统复位的地方,可以往下单步跟踪。 ①从系统初始化开始执行,将函数地址赋给R0寄存器,跳转到R0地址执行并返回此处(BLX是带链接的跳转,即带返回的跳转)。 ②将main函数地址给R0,将函数地址赋给R0,跳转到R0地址执行,不返回(BX是跳转,不返回)。 ③跳转到了$Sub$$main。 【注:在 __CC_ARM 编译器环境下,使用了$Sub$$ 与$Super$ $ 的...

yang1111111112的博客 1万+

Android ImageView的Tint属性

Android Tint使用 Tint 属性   Tint 是 Android5.0 引入的一个属性,它可以在Android5.0 系统上,对视图进行颜色渲染。  下面是网上一个使用tint属性给背景调整不同颜色的例子: &lt;LinearLayout android:orientation="horizontal" android:layout...

u013252110的博客 6291

Playwright与MCP协议结合:AI驱动的智能Web自动化测试实践

Web自动化测试是现代软件开发流程中保障产品质量的关键环节,其核心原理是通过程序模拟用户操作,对Web应用进行功能验证。传统自动化测试工具如Selenium和Playwright虽然提供了强大的API,但脚本编写和维护仍需较高的编程技能。随着AI技术的发展,智能测试成为新的趋势,它通过自然语言理解和自动化执行,显著降低了测试创建门槛。Model Context Protocol(MCP)作为一种连接AI模型与外部工具的开放协议,为自动化测试带来了“智能大脑”。通过将MCP与Playwright结合,测试人员

aoe41606的博客 604

Andorid-Tint使用与原理解析

Android Tint使用Tint 属性  Tint 是 Android5.0 引入的一个属性,它可以在Android5.0 系统上,对视图进行颜色渲染。 下面是网上一个使用tint属性给背景调整不同颜色的例子: <LinearLayout android:orientation="horizontal" android:layout_width="wra

Knight-ZXW的博客 1万+

PCB光绘文件DFM检查:从Gerber验证到制造闭环

Gerber文件是PCB设计交付制造的核心数据载体,其准确性直接决定硬件可制造性与量产良率。理解Gerber格式规范、IPC网表比对原理及DFM(Design for Manufacturability)自动检测逻辑,是电子工程师保障设计落地的关键能力。通过电气连通性验证、物理DRC规则扫描与工艺兼容性分析,DFM工具能提前识别开路、短路、孔环不足、阻焊异常等典型问题,避免投板后返工甚至批量报废。在国产化替代趋势下,华秋DFM等平台已深度适配Altium Designer工作流,支持一键导入、智能报告与协同

weixin_42620563的博客 507

C#实战:从零搭建Vosk离线语音转文字系统

本文手把手教你用C#构建离线语音转文字系统,基于NAudio和Vosk实现全流程开发。首先介绍环境搭建,包括NuGet包安装和中文模型配置,强调16kHz单声道音频格式的关键性。接着详细解析音频预处理转换、Vosk模型初始化及识别过程的核心代码,提供多线程优化建议和实时识别扩展思路。文章包含80%以上代码注释,从常见问题排查到性能优化技巧,完整覆盖从"Hello World"到工业级部署的关键技术点,特别适合需要开发本地化语音识别应用的C#开发者。

墨夶的博客 752

Android着色器Tint研究

Tint 这个东西 主要用来减少apk体积的,比如说我现在有一个textview,他的背景图 有两种,一种是当获得焦点时显示的a图,另一种是 失去焦点时显示的b图。 相信大家开发的时候 这种需求做过很多次了,我们一般都会发现 这种a图和b图 除了颜色不一样,其他都是一样的,但是我们做的时候呢,通常是找ui要了两张图。 如果要适配分辨率的话 很有可能图片...

weixin_34356555的博客 127

在最新版eclipse中配置使用AI AIcoder _AIcoder配置GPUSTACK使用_配置OLLAMA本地AI模型利用_集合---AI场景应用工作笔记

本文介绍了三款实用的编程辅助工具:一款便捷的反编译插件,可直接在插件市场安装使用;GitHub Copilot提供每月2000次代码补全和50条聊天记录的免费额度,支持智能代码提示功能;aicoder支持配置本地模型运行。这些工具都能有效提升开发效率,其中GitHub Copilot的智能补全功能尤为突出。

添柴程序猿的专栏 1227

Android Tint着色器

1.tint Tint着色器可以使图片变色,使用tint可以显示不同颜色的图片。 Tint着色器效果是将非透明的像素点渲染成指定的颜色。比如给定一个白色图标图片,如果要显示不同的颜色,可以直接在ImageView中设置android:tint或app:tint属性,设置一个颜色值即可将该图片显示为指定颜色的图片。这样同一张图片可以显示多种不同颜色的效果,从而减少APK打包的图片数量,也就减少了APK安装包的大小。 2.基本用法 Tint基本用法就是在ImageView组件中添加app:tint

zenmela2011的专栏 3337

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Android 着色器 Tint

转:  安卓着色器(tint)使用实践。           Drawable的Tint变色(让Android也能有iOS那么方便的图片色调转换) 安卓着色器(tint)使用实践。 学习tint的目的: 1.一张矢量图适配所有颜色(妈妈再也不要担心我找图了)。 2.更优雅的selector实现方式。 盗用一张图 小试牛刀,一张矢量图

wxx614817的专栏 966

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【Android 安装包优化】Tint 着色器 ( 简介 | 布局文件中的 Tint 着色器基本用法 | 代码中使用 Tint 着色器添加颜色效果 )

一、Tint 着色器简介、 二、布局文件中的 Tint 着色器基本用法、 三、代码中使用 Tint 着色器添加颜色效果、 四、参考资料、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 3237

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Android--安卓着色器(tint)使用实践

安卓着色器(tint)使用实践。 字数1382 阅读1535 评论26 喜欢45 学习tint的目的: 1.一张矢量图适配所有颜色(妈妈再也不要担心我找图了)。 2.更优雅的selector实现方式。 盗用一张图 小试牛刀,一张矢量图适配所有颜色。 如何在代码中实现下图效果 效果1 方法一:xml 方法很简

Navan 976

android tint着色器(蒙层/阴影等)

1.需求分析:   当我们需要同一张图片进行细微处理(eg.图片的颜色变暗、变浅等)时,一般的做法有以下几种: ①通过alpha设置透明度,让一个深颜色的图片变浅   ———— 该方法适合有透明需求时 ②通过selector切换图片  ———— 该方法往往伴随着点击等事件。而且若是图片原型相同,仅为改变里面的部分参数如色值等而用此方法,容易造成资源的浪费,以及最后安装包的过于庞大。因此,

qq_37077360的博客 2248

Android | Tint 着色器

Tint是一种用于Android 视图(例如按钮和图像视图)的颜色过滤器,其效果是将非透明的像素点渲染成指定的颜色。说白了就是它会把带有颜色的部分替换成另一种颜色。

ezsxrtghjmk的博客 1288

Android着色器tint相关剖析

tint一个很陌生,甚至以前都不知道的东西,从它的字面意思来讲呢是色彩、着色的意思。他其实时Google官方在Material Design中一个很重要的东西,搭配background一起使用。如果你平时细心或者最佳使用 过EditText的话,你会发现,EditText下面的指示器颜色一直与你颜色资源文件中的colorAccent对应的值一样(感兴趣的朋友可以自己尝试修改),当然如果你不想去改变

野生程序员 715

android动态设置tint,Android Tint的简单使用

Android Tint的简单使用如果要实现下图效果,第一时间想到的是让 UI 切图,第二时间想到的是自己会被 UI 打死,第三时间想到的是自己会被命名累死。![屏幕快照 2016-10-13 下午9.58.26](http://odsdowehg.bkt.clouddn.com/屏幕快照 2016-10-13 下午9.58.26.png)那么,这该如何快速高效的实现呢? 其实 Android 已...

weixin_42543046的博客 1590

探索Android Material Design 中的Tint(着色)

很多天以前看到鸿洋大神公众号推出的一篇文章:安卓着色器(tint)使用实践,开始接触Tint这个属性,Tint翻译为着色,用于对视图进行颜色渲染。和往常一样,主要还是想总结一下我在学习过程中的一些笔记以及一些需要注意的地方。一、Tint的作用 Tint的存在一定程度上减少了我们对图片的需求以及apk的大小,我们拿ImageView来说吧,假如它的背景图有两种,一种是默认情况下需要显示的是背景图片1

Angelica 8314

android代码设置drawor色值,Android 着色器 tint

本文主要总结了 Android 着色器的使用及其原理,在实现同等效果的情况下,减少资源图的使用以减小 apk 包的体积并降低对内存的占用。假设我们想实现一种效果,如下:不怎么友好的做法是让设计师给五张资源图,然后依次排列五个对应的 ImageView。这种做法是存在一些问题的,apk 包体积增加了五张图的大小;程序运行时内存增加了五张图的大小。这时,我们就可以考虑使用着色器来简单快捷高效地实现这个...

weixin_36483061的博客 1157
上一篇: 谈谈Android Material Design 中的Tint(着色)
下一篇: 面试题:如何优化ListView的性能?
AuthFailure
博客等级 码龄10年 0粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值