当前位置: 首页 > news >正文

Android 应用使用theme处理全局焦点框

背景

  • 我的应用有个需求,要求处理keycode事件,进行焦点移动处理,必须定制指定的焦点框。
  • 而系统的焦点框是固定了,为了保证平台的一致性,没办法直接修改。

问题

  1. 经过沟通,大部分都是自行修改了自己的background的属性,定制了焦点框,因为所需要处理的焦点框数量有限,进行了特殊修改
  2. 我的应用涉及的内容比较多,如果一个个修改,不仅工作量很大,还需要新增很多布局,并且修改掉原来的架构。

尝试

查看源码焦点框如何处理

系统也只是在overlay下面配置了一个属性,属性如下:

<item name="android:selectableItemBackground">@*android:drawable/item_background</item>

给这个属性配置了一个选择器,只要修改这个选择器,就可以改变系统全局焦点框。

是否有方法可以新增theme替换?

经过资料查询,需要新增一套主题包,替换才能起作用,工作量和周期太长,无法短时间内完成,且需要配合的相关方太多,暂时放弃此方案

是否可以在自己应用内部修改主题?

修改application应用的主题

  1. 首先修改应用自己的默认主题
<style name="Theme.system" parent="Theme.AppCompat.DayNight"><item name="android:windowNoTitle">true</item><item name="android:windowFullscreen">false</item><!-- 兼容API 7--><item name="android:windowActionBar">false</item><item name="android:windowIsTranslucent">true</item><item name="android:selectableItemBackground">@drawable/item_all_app_selector</item>
</style>
  1. Selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_focused="true"><shape android:shape="rectangle"><solid android:color="@color/transparent" /><stroke android:width="8dp" android:color="@color/view_on_click_background" /></shape></item><item android:state_focused="false"><shape><solid android:color="@color/transparent" /></shape></item></selector>
  1. 由于应用的特殊性,是没有Activity存在的,由addview和系统AlterDialog组成,修改系统主题之后,是没办法直接使用的。
  2. 首先修改系统Alter Dialog手动给他加载主题
private var mAllAppDialog: AllAppDialog = AllAppDialog(Utils.getContext(),R.style.Theme_dialog)
  1. 显示出来之后,发现有问题,因为之前是使用的系统默认的主题,加载了自定义主题时候,整个效果发生了变化,背景颜色和原有的高斯模糊都失效了,但是修改的焦点框是可以生效的
  2. 随后进行分析,我们使用的是通用的应用主题,也就是parent=“Theme.AppCompat.DayNight” 的主题是没办法给系统级别的AlterDialog用的。他不仅会给AlterDialog增加一个承载的黑色背景还会修改显示效果。
  3. 查看源码,源码是有专门为AlterDialog使用的主题。

创建新的主题

  1. 查看源码得到方向后,创建新的主题,parent=“Theme.AppCompat.Dialog.Alert”。仅增加一个指定的焦点框,并且修改背景为透明
<style name="Theme.dialog" parent="Theme.AppCompat.Dialog.Alert"><item name="android:selectableItemBackground">@drawable/item_all_app_selector</item><item name="android:background">@color/transparent</item>
</style>
  1. 再次尝试加载,加载成功,可以正常显示
  2. 扩展到其他的AlterDialog,统一使用加载指定的主题

异常情况

  1. 当扩展到其他的AlterDialog之后,发现有一个部分AlterDialog是无法正常加载主题的
  2. 因为每个对话框的业务逻辑和显示效果不同,一时没有分析到指定的问题
  3. 对比两类对话框,也没发现具体的问题原来
  4. 查找资料,也没有相关的资料说明
  5. 切换方向思考,对Context进行处理,为他加载主题
fun getWrapperContext():ContextThemeWrapper{return  ContextThemeWrapper(Utils.getContext(),R.style.Theme_dialog)
}
  1. 使用新的Context,进行调试,可以生效。将所有异常的AlterDialog全部使用新的Content处理。
private var mMessageDialog: MessageDialog = MessageDialog(getWrapperContext())
private var mAccountDialog: AccountDialog = AccountDialog( getWrapperContext())

addview处理

  1. WindowManager 的addView方法进行加载的。addview方法是没办法直接加载主题的。
  2. 使用加载主题的Context初始化需要加载的View,再进行加载。主题正常加载
val wContext=ContextThemeWrapper(mContext,R.style.Theme_dialog)
Bar = View.inflate(wContext, R.layout.bar_view, null)
  1. 效果如下:

总结

修改应用全局焦点框

只对activity生效,主题如下

<style name="Theme.system" parent="Theme.AppCompat.DayNight"><item name="android:windowNoTitle">true</item><item name="android:windowFullscreen">false</item><!-- 兼容API 7--><item name="android:windowActionBar">false</item><item name="android:windowIsTranslucent">true</item><item name="android:selectableItemBackground">@drawable/item_all_app_selector</item>
</style>

修改指定的View焦点框

所有控件都可以用

<style name="Theme.dialog" parent="Theme.AppCompat.Dialog.Alert"><item name="android:selectableItemBackground">@drawable/item_all_app_selector</item><item name="android:background">@color/transparent</item>
</style>

构建带主题的Context

fun getWrapperContext():ContextThemeWrapper{return  ContextThemeWrapper(Utils.getContext(),R.style.Theme_dialog)
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java Web实战:利用三层架构与Servlet构建登录注册模块
  • 【Echarts】使用多横坐标轴展示近十五天天气预报
  • 连年(年份)
  • 在国内版Office 365中通过PowerShell命令查询指定主题的邮件详解
  • 轻量级模型解读——基于神经网络架构搜索(NAS)系列
  • 开放式耳机有哪些值得推荐?十大口碑最好开放式蓝牙耳机!
  • 科技与艺术完美融合的LED异形创意圆形(饼/盘)显示屏横空出世
  • 开放式蓝牙耳机推荐?五款高评分爆款机型汇总!
  • 设计模式---中介者模式
  • C++标准的一些特性记录:C++11的constexpr
  • 4G工业路由器:SR700的智能连接解决方案
  • EasyExcel拿表头(二级表头)爬坑,invokeHeadMap方法
  • 音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件
  • 如何利用 CSS 渐变实现多样化背景效果
  • 【C++11 —— 包装器】
  • co.js - 让异步代码同步化
  • CSS3 变换
  • docker-consul
  • ES6 ...操作符
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • java 多线程基础, 我觉得还是有必要看看的
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript的使用你知道几种?(上)
  • JavaScript类型识别
  • js学习笔记
  • js正则,这点儿就够用了
  • maya建模与骨骼动画快速实现人工鱼
  • web标准化(下)
  • Web设计流程优化:网页效果图设计新思路
  • 近期前端发展计划
  • 聚簇索引和非聚簇索引
  • 那些年我们用过的显示性能指标
  • 排序算法之--选择排序
  • 使用parted解决大于2T的磁盘分区
  • 手写一个CommonJS打包工具(一)
  • 用mpvue开发微信小程序
  • 最简单的无缝轮播
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​比特币大跌的 2 个原因
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #QT(智能家居界面-界面切换)
  • #微信小程序:微信小程序常见的配置传值
  • $.proxy和$.extend
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (web自动化测试+python)1
  • (翻译)terry crowley: 写给程序员
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011