此文章为自我的学习感悟和总结,希望可以给大家带来帮助,如有不足,请各位大佬直接点出

相信大家都接触过黑白化的App和页面,虽然它出现的次数很少但是我们还是逃不了它的出现,现在各大App都会加入这个置灰配置,在我不知所措的时候看到了鸿洋大神的这两篇文章,让我犹如神助,建议大家可以先看看鸿洋大神的这两篇之后再来看这篇,大神两篇文章在此

↓↓↓
App 黑白化实现探索,有一行代码实现的方案吗?
App 黑白化实现探索2,发现了一种更方便的方案,我被锤了!

置灰方法

由于没有什么合适的图所以从鸿洋大神那里拿过来的效果图
↓↓↓


相信大家看完鸿洋大神的文章以后已经有所思路和感悟了,一些参数之类的我在这里就不细讲了,就大概讲一下,分别是以下两种方法:

重写draw方法:

   Paint paint = new Paint();ColorMatrix colorMatrix = new ColorMatrix();colorMatrix.setSaturation(0);mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));@Overridepublic void draw(Canvas canvas) {if (paint != null) {canvas.saveLayer(null, paint , Canvas.ALL_SAVE_FLAG);super.draw(canvas);canvas.restore();} else {super.draw(canvas);}}@Overrideprotected void dispatchDraw(Canvas canvas) {if (paint != null) {canvas.saveLayer(null, paint , Canvas.ALL_SAVE_FLAG);super.dispatchDraw(canvas);canvas.restore();} else {super.dispatchDraw(canvas);}}

分为三步:

1.创建画笔和颜色矩阵
2.将颜色矩阵设置为灰色也就是Saturation赋值为0,再把颜色矩阵给画笔设上,相当于一只灰色的笔
3.重写draw方法,调用canvas的saveLayer把我们创建的画笔传进去,相当于用我们灰色的画笔将画布画灰(dispatchDraw方法为将它向下去分发绘制,它的子类都会被画灰,若只需当前页面置灰那么就不用重写此方法)

硬件加速方法:

   View rootView = inflater.inflate(R.layout.activity_main,null);Paint paint = new Paint();ColorMatrix colorMatrix = new ColorMatrix();colorMatrix.setSaturation(0);paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));//针对某个View置灰rootView.setLayerType(View.LAYER_TYPE_HARDWARE,paint);//若想直接将Activity置灰则使用下行getWindow.getDecorView.setLayerType(View.LAYER_TYPE_HARDWARE, paint);

我一般使用它都是简单粗暴,哪个View需要置灰直接给这个View调setLayerType把你的灰色画笔放进去

也是分为三步:

1.创建画笔和矩阵
2.将颜色矩阵设置为灰色也就是Saturation赋值为0,再把颜色矩阵给画笔设上,相当于一只灰色的笔
3.给所需要的的View用setLayerType把画笔传进去

共同点:都是要首先创建画笔和颜色矩阵,将颜色矩阵设置为灰色,再将颜色矩阵赋给画笔

区别:第一个方法会影响到一些特殊的控件(如webview、H5页面、视频等)。第二个方法会依赖硬件加速,不过现在应用都会开硬件加速,其他问题暂未发现。

总结:不能说哪个方法最好,哪个方法没有任何影响,只能说两个方法各有各的优点和缺点,我们可以将两个方案放在一起使用,扬长避短,互补一下,普通页面用第一种方法,特殊控件的时候用第二种方法,混合一下。

-------------------------------------------------------分割线---------------------------------------------------------

置灰实践

思路:首先确定好使用哪种方法进行置灰,确定自己的项目中是否有特殊控件。我这里是将两种方法一起使用,先将有特殊控件的地方记录下来,再去确定其他普通页面。

首先创建一个置灰的管理类:

public class GrayManager {public static final int GRAY_SWITCH_CLOSE = 0;//未置灰public static final int GRAY_SWITCH_OPEN = 1;//置灰private static GrayManager mInstance;private int mGraySwitch;private long mStartTime;private long mEntTime;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() {mGraySwitch = SpUtil.SP.getInt(SpUtil.KEY_PAGE_GRAY_SWITCH, GRAY_SWITCH_CLOSE);mStartTime = SpUtil.SP.getLong(SpUtil.KEY_PAGE_GRAY_START_TIME, GRAY_SWITCH_CLOSE);mEntTime = SpUtil.SP.getLong(SpUtil.KEY_PAGE_GRAY_END_TIME, GRAY_SWITCH_CLOSE);if (!isShowTime(mStartTime, mEntTime)) {mGraySwitch = GRAY_SWITCH_CLOSE;}mGrayMatrix = new ColorMatrix();mGrayPaint = new Paint();mGrayMatrix.setSaturation(0);mGrayPaint.setColorFilter(new ColorMatrixColorFilter(mGrayMatrix));}//获取置灰开关public int getGraySwitch() {return mGraySwitch;}//更新数据private void updateData(int grayType, long startTime, long endTime) {SpUtil.SP.applyInt(SpUtil.KEY_PAGE_GRAY_SWITCH, grayType);SpUtil.SP.applyLong(SpUtil.KEY_PAGE_GRAY_START_TIME, startTime);SpUtil.SP.applyLong(SpUtil.KEY_PAGE_GRAY_END_TIME, endTime);}//设置置灰数据public void setServerGray(GrayBean bean) {if (bean != null && isShowTime(bean.getStartTime(), bean.getEndTime())) {updateData(bean.getType(), bean.getStartTime() , bean.getEndTime());} else {updateData(GRAY_SWITCH_CLOSE, 0 , 0);}}//硬件加速置灰方法public void setLayerGrayType(View view) {if (mGrayMatrix == null || mGrayPaint == null) {init();}if (mGraySwitch == GRAY_SWITCH_OPEN ){view.setLayerType(View.LAYER_TYPE_HARDWARE,mGrayPaint);}}//判断是指定时间生效还是永久生效private boolean isShowTime(Long startTime, Long endTime) {long time = System.currentTimeMillis();return startTime < time && endTime > time;}//获取灰色画笔public Paint getGrayPaint() {if (mGrayPaint != null && mGrayMatrix != null && mGraySwitch == GRAY_SWITCH_OPEN){return mGrayPaint;}return new Paint();}
}

这是一个置灰管理类,我这里用SP存储去存所获取的数据,也加入了生效时间的判断,大家可以根据各自的需求去写,我把第二个方法,也就是硬件加速的置灰放到了这个类里面,哪个特殊控件需要置灰的话直接调用setLayerGrayType()方法将view传进去就ok。
比如我想让某个Fragment置灰,那我就在Fragment里面调用:

GrayManager.getInstance.setLayerGrayType(getRootView())

创建自定义的置灰View(根据需求创建,这里只展示FrameLayout):

public class GrayFrameLayout extends FrameLayout{private Paint mPaint;public GrayFrameLayout(Context context, AttributeSet attrs) {super(context, attrs);setGray();}private void setGray() {if (GrayManager.getInstance.getGraySwitch() == GrayManager.GRAY_SWITCH_OPEN) {mPaint = new Paint();ColorMatrix colorMatrix = new ColorMatrix();colorMatrix.setSaturation(0);mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));} else {mPaint = null;}}@Overridepublic void draw(Canvas canvas) {if (mPaint != null) {canvas.saveLayer(null, mPaint, Canvas.ALL_SAVE_FLAG);super.draw(canvas);canvas.restore();} else {super.draw(canvas);}}@Overrideprotected void dispatchDraw(Canvas canvas) {if (mPaint != null) {canvas.saveLayer(null, mPaint, Canvas.ALL_SAVE_FLAG);super.dispatchDraw(canvas);canvas.restore();} else {super.dispatchDraw(canvas);}}
}

之后哪里需要置灰直接把布局换成这个就可以,比较简单,大家可以根据需求创建对应的view和逻辑

总结:目前基本上是这个样子吧,普通页面呢就将布局替换为自定义的,特殊控件呢就调用Manager内的方法。

注意:置灰只是绘制当前页面,遇到截图时截图是未置灰的(非系统截图,如侧滑返回时上个页面在滑动时未置灰),所以我在Manager类里面增加了灰色画笔,若截图是使用Paint和Canvas绘制的那么可以调用GrayManager.getInstance().getGrayPaint(),将此画笔传入Canvas。

若大佬们有更好的方案和方法去进行置灰处理记得告诉我哦~

关于App置灰黑白化的探索相关推荐

  1. Android APP全局黑白化实现方案

    作者:小帅 链接:https://zhuanlan.zhihu.com/p/587516253 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 在清明节时各大APP都 ...

  2. 安卓APP全局黑白化实现方案

    感谢大家和我一起,在Android世界打怪升级! 在清明节时各大APP都会进行黑白化处理,当时在接到这个需求的时候感觉好麻烦,是不是又要搞一套皮肤? 然而在一系列搜索之后,找到了两位大神(鸿洋.U2t ...

  3. 企查查app sign算法破解初步探索

    企查查app sign算法破解初步探索 之前有说过企查查的sign的解密,但这次是企查查app的sign算法破解,目前是初步进程. 目前我们需要做查壳,具体方法可以百度搜索,企查查用的360加固,很简 ...

  4. 全局置灰操作:小程序置灰、app置灰、H5置灰

    微信小程序全局置灰: 只需要在app.wsxx文件中添加一行代码: page {filter: grayscale(100%);} 也可以写到对应的页面中,xxx.wsxx 文件中添加:page {f ...

  5. android探索宇宙app,AR研学星系探索app

    AR研学星系探索app是一款为喜欢探索宇宙的用户们提供的关于八大行星学习的软件:通过VR虚拟的形式让用户可以更加直观地了解到我们的地球和我们的浩瀚的宇宙,来启发用户对宇宙的探索和好奇.这款软件会为用户 ...

  6. uniapp app端导出excel的探索和实现(二)

    一.前言 之前在app中使用html模板导出的.xlsx的兼容性不好,只能在wps中直接打开,在MIcrosoft的excel中直接甩给我一个警告: 于是,又一次进入"轻松愉快"的 ...

  7. android 黑屏手势动画,Android MIUI 即刻APP 返回手势及动画 探索

    swipe_left.jpeg swipe_right.jpeg 18 年底做 Readhub APP 时就加入了这个返回动画效果.一直到现在,才有时间来简单总结和封装一下. swipeback.gi ...

  8. 你是否了解APP耗电问题?深入探索 Android 电量优化,flutter插件推荐

    3).最后,把电量输送给电池,而整个降压的过程中会产生热能. 分类 1).高压低电流快充方案:在充电过程中提升充电电压(7-20V)来提升充电功率. 2).低压大电流快充方案:在电压一定情况下,增加电 ...

  9. 数据标准化与PCA白化原理探索

    PCA是实验中很常用的工具,一般用来做降维,它的实现有很多很多种,其中牵涉相当多的细节,笔者在实现PCA时常常有困惑,为什么查到的各种代码总有一些不同的trick,有时候对样本提前归一化?有时候又要减 ...

最新文章

  1. html 简单机器人对话页面,简单的js聊天机器人框架BotUI
  2. idea springmvc_SSM三大框架使用Maven快速搭建整合(SpringMVC+Spring+Mybatis)
  3. 服务器被非法上传文件,DiscuzX没有合法的文件被上传的修复方法
  4. 【转】简述configure、pkg-config、pkg_config_path三者的关系
  5. 关于HTML Object中三个Style实例的区别
  6. 【二分法万能模板】Leecode 74. 搜索二维矩阵——Leecode日常刷题系列
  7. SPOJ687 Repeats(重复次数最多的连续子串)
  8. redhat9安装mysql_redhat 9.0 安装mysql
  9. Alter操作(修改列名,修改列数据类型,增加列,删除列,增加列且设为主键及对默认值操作)
  10. keystore是个嘛东西
  11. 深度学习(2) - 感知器
  12. java 输出视频文件格式_java – 如何从各种视频文件格式中提取元数据?
  13. 项目部署,环境搭建(pip/ makefile)
  14. zoj 2966 Build The Electric System
  15. 基于 CODING 的 Spring Boot 持续集成项目 1
  16. uniapp 生成 海报
  17. access订单明细表怎么做_图书销售订单明细表
  18. usb调试助手_【小白教程】如何使用米卓同屏助手?
  19. spring框架特点
  20. 分布式异步任务框架之Celery定义、异步任务框架特点、架构、使用场景、安装配置、基本使用、多任务结构使用、延时任务、定时任务及django中使用celery

热门文章

  1. Vue全家桶系列之Vuex(三)
  2. 普通电脑可以装苹果系统吗?Windows电脑装Mac系统
  3. 拥有普通的人平凡、幸福和英雄般坚持---Leo读《不是孙振耀写的职场感言》(4)
  4. 【poj 1182】食物链 并查集应用
  5. 诺依曼计算机组成,1.1.2 冯·诺依曼计算机模型
  6. python字符串模糊匹配 - FuzzyWuzzy
  7. 安卓手机”应用未安装“解决办法
  8. Vmware Ubuntu 无法解析域名解决
  9. 衡水学院计算机实习,衡水学院教育实习系列报道之三
  10. Unity WebGL 下载替换Word模板数据