# Android实现灰度模式 站点:答源(https://www.dandroid.cn/) 原文:https://www.dandroid.cn/archives/21863 Canonical:https://www.dandroid.cn/archives/21863 作者:admin 发布日期:2023-11-23 最后更新:2023-11-23 06:26 分类:技术方案 内容类型:post 说明:本页是原文的纯文本镜像,供大模型与检索器完整读取;不含导航、广告、付费框。引用请以上方「原文」链接为准。 ## 正文 App快速实现“哀悼主题”方案 方式一:全局设置灰白模式: @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Paint paint = new Paint(); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0);//灰度效果 paint.setColorFilter(new ColorMatrixColorFilter(cm)); getWindow().getDecorView().setLayerType(View.LAYER_TYPE_HARDWARE,paint); } 创建一个置灰的管理类 public class GrayManager { private static GrayManager mInstance; private Paint mGrayPaint; private ColorMatrix mGrayMatrix; public static GrayManager getInstance() { if (mInstance == null) { synchronized (GrayManager.class) { if (mInstance == null) { mInstance = new GrayManager(); } } } return mInstance; } //初始化 public void init() { mGrayMatrix = new ColorMatrix(); mGrayPaint = new Paint(); mGrayMatrix.setSaturation(0); mGrayPaint.setColorFilter(new ColorMatrixColorFilter(mGrayMatrix)); } //硬件加速置灰方法 public void setLayerGrayType(View view) { if (mGrayMatrix == null || mGrayPaint == null) { init(); } view.setLayerType(View.LAYER_TYPE_HARDWARE, mGrayPaint); //view.setLayerType(View.LAYER_TYPE_SOFTWARE, mGrayPaint); 不能用硬件加速的方法 } } 特殊控件需要置灰的话直接调用setLayerGrayType()方法将view传进去,比如demo中让某个Activity置灰,那就在Activity里面调用 GrayManager.getInstance().setLayerGrayType(getWindow().getDecorView());  方式二: 将 App 页面置灰有多种实现方案,例如,最简单的实现方式是,在 App 内置 2 套切图及对应的 2 套色值资源文件等,根据全局置灰开关,选择加载不同的图片和色值。这种方案全局实现起来工作繁琐、工作量大。且会导致 App 包增大很多,用户体验差,不是一种很好的实现方案。 实现灰度化的思路应该从 Android 系统界面绘制原理出发寻找实现方案。系统是通过 Paint 将内容绘制到界面上的,Paint 中可以设置 ColorMatrix ,界面置灰可以通过通过使用颜色矩阵(ColorMatrix)来实现。 在 Android 中,系统使用一个颜色矩阵 ColorMatrix,来处理图像的色彩效果。通过这个类,可以很方便地改变矩阵值来处理颜色效果。ColorMatrix 提供了以下关键方法进行对颜色的处理: setRotate(int axis, float degree) :设置颜色的色调,第一个参数,系统分别使用0、1、2 来代表 Red、Green、Blue 三种颜色的处理;而第二个参数,就是需要处理的值。 setSaturation(float sat):设置颜色的饱和度,参数代表设置颜色饱和度的值,当饱和度为0时,图像就变成灰度图像。 setScale(float rScale, float gScale, float bScale , float aScale):对于亮度进行处理。 实现去色重点用到了 ColorMatrix 类中的 setSaturation 方法,查看官网 API 对这个方法有这么一段说明:“Set the matrix to affect the saturation of colors. A value of 0 maps the color to gray-scale. 1 is identity. ” 意思是去设置颜色矩阵的饱和度,0 是灰色的,1 是原图。通过调用 setSaturation (0) 方法即可将图像置为灰色 。通过继承 ImageView 实现该方案验证,具体代码如下: class GrayImageView extends ImageView { private Paint mPaint; public GrayImageView(Context context) { super(context,null); } public GrayImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.setSaturation(0); mPaint.setColorFilter( new ColorMatrixColorFilter(colorMatrix)); } @Override protected void onDraw(Canvas canvas) { canvas.saveLayer(null,mPaint,Canvas.ALL_SAVE_FLAG); super.onDraw(canvas); } } 测试效果如下: 以上是在 ImageView 中实现灰度化。针对其他控件例如 TextView 实现也是一样的,因为本质都是使用 Paint 进行的绘制,通过自定义 TextView 添加上面的代码也同样可以实现。通过自定义 View 可以实现颜色置灰,但是在项目里有很多的 ImageView、 TextView 等等各种控件,一个个替换工作量也特别的大。 方案优化 从上面 ImageView 的置灰实现猜测是否所有的 View 都能给置灰,DecorView 是 Activity 窗口的根视图,根视图通过 ColorMatrix 设置置灰应该可以在全部子元素有效。在 BaseActivity 中添加代码如下: @Override protected void onCreate(Bundle savedInstanceState) { val paint = Paint() val cm = ColorMatrix() cm.setSaturation(0f) paint.colorFilter = ColorMatrixColorFilter(cm) window.decorView.setLayerType(View.LAYER_TYPE_HARDWARE, paint) }  测试所有的界面均变为灰色,效果如图: 这两种方式使用很少的代码就实现了全局的置灰处理,明显提升了替换效率。 --- 由 答源 DAN 底座 1.4.0 生成 · 2026-11-08T15:07:38+00:00