Android实现灰度模式

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)
}

 测试所有的界面均变为灰色,效果如图:

这两种方式使用很少的代码就实现了全局的置灰处理,明显提升了替换效率。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/21863,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?