Android 深色模式适配原理分析( 七 )
frameworks/base/libs/hwui/RenderProperties.h
/* * Data structure that holds the properties for a RenderNode */class ANDROID_API RenderProperties {public:// ...// 设置View是否允许强制深色模式bool setAllowForceDark(bool allow) {return RP_SET(mPrimitiveFields.mAllowForceDark, allow);}// 获取View是否允许强制深色模式bool getAllowForceDark() const {return mPrimitiveFields.mAllowForceDark;}// ...private:// Rendering propertiesstruct PrimitiveFields {// ...// 默认值为truebool mAllowForceDark = true;// ...} mPrimitiveFields;
我们回头看下上面分析过的RenderNode.cpp的prepareTreeImpl流程
frameworks/base/libs/hwui/RenderNode.cpp
// 经过了简化处理的prepareTreeImpl逻辑void RenderNode::prepareTreeImpl(TreeObserver}// 同步正在处理的Render Node的Display List , 实现具体深色的逻辑pushStagingDisplayListChanges(observer, info);mDisplayList->prepareListAndChildren([](RenderNode* child, TreeObserver});// 递归结束后将之前设置过+1的值做回退-1恢复操作 , 避免影响其他兄弟结点的深色模式值判断if (!mProperties.getAllowForceDark()) {info.disableForceDark--;}}
可以看出 , 设置View的forceDarkAllowed最终会设置到当前RenderNode的mProperties.allowForceDark属性中 , 并在RenderNode遍历的过程中影响深色模式的执行 。
我们可以以下面的伪代码来更直观地了解深色模式执行的流程:
// 深色模式渲染伪代码int disableDark = if (themeAllowDark) 0 else 1;void RenderNode(Node node) {if (!node.allowDark) {disableDark++;}if (disableDark == 0) forceDarkCurrentNode();for (child : node.children) {RenderNode(child)}if (!node.allowDark) {disableDark--;}}
至此 , 我们分析完所有强制深色模式的原理 。 总结一下 , 主题默认不会强制深色 , 若主题设置了强制深色 , 则遍历View树对其节点进行强制深色转换 。 碰到某个View不希望被强制深色 , 则包括它和它的所有子节点都不会被强制深色 。
总结到这里 , 我们了解了可以通过设置-night资源以及判断当前颜色模式来自定义切换主题、色值、图片和动画的颜色 , 也从源代码角度了解Force Dark的原理和生效规则 。
推荐阅读
- 诺基亚为何宁可逐渐没落也不采用Android系统?长知识了
- 运动计数开发项目的对抗赛:飞算全自动软件工程平台碾压传统模式
- 莆田:科技与创意引领制鞋新模式
- 华为开启“暴走”模式!三个大动作同时展开,国产芯片将迎来破冰
- 联想发布新款11英寸Android平板电脑Tab P11
- 送餐机器人等创新模式助力餐饮行业复苏发展
- 向日葵Android客户端5.0更新:新增两种免root远控方式
- 一加披露Android 11升级计划 OnePlus 6与Nord 10系列皆有份
- 青少年|封面评论 |“青少年模式”依旧漏洞百出,标准化合规框架必须落地
- 聊聊网易云音乐:“心动模式”