问题现象

上图展示的很清楚,当系统语言为中文时,PreferenceScreen 中的折叠项 summary 描述重复显示的 bug,系统语言为英文时正常。

修改历程

先搜索 当前显示了 字符串,还真找到了

prebuilts\sdk\current\support\v7\preference\res\values-zh-rCN\values-zh-rCN.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources xmlns:ns1="urn:oasis:names:tc:xliff:document:1.2">
  3. <string msgid="3265458434114353660" name="expand_button_title">"高级"</string>
  4. <string msgid="5255557321652385027" name="summary_collapsed_preference_list">"当前显示了 <ns1:g id="CURRENT_ITEMS">%1$s</ns1:g> 项(已添加 <ns1:g id="ADDED_ITEMS">%2$s</ns1:g> 项)"</string>
  5. <string msgid="2082379519172883894" name="v7_preference_off">"关闭"</string>
  6. <string msgid="7922757586228621900" name="v7_preference_on">"开启"</string>
  7. </resources>

再接着搜索 summary_collapsed_preference_list,又找到如下的地方

看着 androidTest 相关的可以忽略,直接看 CollapsiblePreferenceGroupController.java

frameworks\support\preference\src\main\java\androidx\preference\CollapsiblePreferenceGroupController.java

  1. private void setSummary(List<Preference> collapsedPreferences) {
  2. CharSequence summary = null;
  3. final List<PreferenceGroup> parents = new ArrayList<>();
  4. for (Preference preference : collapsedPreferences) {
  5. final CharSequence title = preference.getTitle();
  6. if (preference instanceof PreferenceGroup && !TextUtils.isEmpty(title)) {
  7. parents.add((PreferenceGroup) preference);
  8. }
  9. if (parents.contains(preference.getParent())) {
  10. if (preference instanceof PreferenceGroup) {
  11. parents.add((PreferenceGroup) preference);
  12. }
  13. continue;
  14. }
  15. if (!TextUtils.isEmpty(title)) {
  16. if (summary == null) {
  17. summary = title;
  18. } else {
  19. summary = getContext().getString(
  20. R.string.summary_collapsed_preference_list, summary, title);
  21. }
  22. }
  23. }
  24. setSummary(summary);
  25. }

哈,这下证实了 bug 的由来,summary_collapsed_preference_list 字符串经过格式化 for 循环的叠加自然会出现 当前显示了 当前显示了 当前显示了....

那就简单了,把 summary_collapsed_preference_list 对应的中文字符串修改了就行呗,但是事情没有那么简单,经过修改重新编译测试 bug 依旧,然后又继续搜索,

在 out 目录下还发现了另一个 当前显示了 字符串,文件内容和 prebuilts 下的是一模一样的,但是文件时间却是 2018-05-25 06:04

这就很诡异了,感觉此路不通啊,那好吧,乖乖去捋一捋源码吧

经过简单的分析,找到 Settings 中的 HighlightablePreferenceGroupAdapter

vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\widget\HighlightablePreferenceGroupAdapter.java

  1. import android.support.v7.preference.PreferenceGroup;
  2. import android.support.v7.preference.PreferenceGroupAdapter;
  3. import android.support.v7.preference.PreferenceScreen;
  4. import android.support.v7.preference.PreferenceViewHolder;
  5. import android.support.v7.widget.RecyclerView;
  6. import android.text.TextUtils;
  7. import android.util.Log;
  8. import android.util.TypedValue;
  9. import android.view.View;
  10. import com.android.settings.R;
  11. import com.android.settings.SettingsPreferenceFragment;
  12. public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {

可以看到继承的是 PreferenceGroupAdapter,而且还是 v7 包下面的,继续搜索 PreferenceGroupAdapter.java

https://segmentfault.com/a/1190000020956652

对比 8.1 和 9.0 一看,9.0 已经没有 v7 包支持了,而是改用 androidx 替代,具体介绍可看 Preference组件探究之Base,Support及AndroidX对比

难怪我们上面修改 summary_collapsed_preference_list 没用,上面调用的类 CollapsiblePreferenceGroupController 也是在 androidx 包下,查看 Settings 下的 mk


  1. LOCAL_STATIC_ANDROID_LIBRARIES := \
  2. android-slices-builders \
  3. android-slices-core \
  4. android-slices-view \
  5. android-support-compat \
  6. android-support-v4 \
  7. android-support-v13 \
  8. android-support-v7-appcompat \
  9. android-support-v7-cardview \
  10. android-support-v7-preference \
  11. android-support-v7-recyclerview \
  12. android-support-v14-preference \

android-support-v7-preference 导入静态库,而源码中并没有对应的目录,已经替代为 androidx,悲催了,这下想改资源文件解决bug看来是不行了。

看了下 Android10.0 下 Settings 的 mk,发现已经全部替换为 androidx

Android.mk


  1. LOCAL_STATIC_ANDROID_LIBRARIES := \
  2. androidx-constraintlayout_constraintlayout \
  3. androidx.slice_slice-builders \
  4. androidx.slice_slice-core \
  5. androidx.slice_slice-view \
  6. androidx.core_core \
  7. androidx.appcompat_appcompat \
  8. androidx.cardview_cardview \
  9. androidx.preference_preference \
  10. androidx.recyclerview_recyclerview \
  11. com.google.android.material_material \
  12. setupcompat \
  13. setupdesign

解决办法

通过进一步分析,找到一个关键字段 initialExpandedChildrenCount

vendor\mediatek\proprietary\packages\apps\MtkSettings\res\xml\network_and_internet.xml

  1. <PreferenceScreen
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:settings="http://schemas.android.com/apk/res-auto"
  4. android:key="network_and_internet_screen"
  5. android:title="@string/network_dashboard_title"
  6. settings:initialExpandedChildrenCount="5">

该字段在 PreferenceGroup 中获取并赋值,用来区分当前 Preference 要显示的数量,剩余的需要折叠显示

frameworks\support\preference\src\main\java\androidx\preference\PreferenceGroup.java

  1. public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  2. super(context, attrs, defStyleAttr, defStyleRes);
  3. mPreferenceList = new ArrayList<>();
  4. final TypedArray a = context.obtainStyledAttributes(
  5. attrs, R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);
  6. mOrderingAsAdded =
  7. TypedArrayUtils.getBoolean(a, R.styleable.PreferenceGroup_orderingFromXml,
  8. R.styleable.PreferenceGroup_orderingFromXml, true);
  9. if (a.hasValue(R.styleable.PreferenceGroup_initialExpandedChildrenCount)) {
  10. setInitialExpandedChildrenCount((TypedArrayUtils.getInt(
  11. a, R.styleable.PreferenceGroup_initialExpandedChildrenCount,
  12. R.styleable.PreferenceGroup_initialExpandedChildrenCount, Integer.MAX_VALUE)));
  13. }
  14. a.recycle();
  15. }

最终在 CollapsiblePreferenceGroupController 中读取该字段,判断是否需要添加 ExpandButton 即高级折叠下拉按钮

所以我们只需要将 initialExpandedChildrenCount 设置成最大即可,Preference 将不再折叠,当然这是一种偷懒的做法,这样会失去原来的用户体验

vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\widget\HighlightablePreferenceGroupAdapter.java

  1. /**
  2. * Tries to override initial expanded child count.
  3. * <p/>
  4. * Initial expanded child count will be ignored if:
  5. * 1. fragment contains request to highlight a particular row.
  6. * 2. count value is invalid.
  7. */
  8. public static void adjustInitialExpandedChildCount(SettingsPreferenceFragment host) {
  9. Log.e("HighlightablePreferenceGroupAdapter"," adjustInitialExpandedChildCount()");
  10. if (host == null) {
  11. return;
  12. }
  13. final PreferenceScreen screen = host.getPreferenceScreen();
  14. if (screen == null) {
  15. return;
  16. }
  17. final Bundle arguments = host.getArguments();
  18. if (arguments != null) {
  19. final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY);
  20. if (!TextUtils.isEmpty(highlightKey)) {
  21. // Has highlight row - expand everything
  22. screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
  23. return;
  24. }
  25. }
  26. final int initialCount = host.getInitialExpandedChildCount();
  27. //cczheng add for expand everything preference S
  28. Log.e("HighlightablePreferenceGroupAdapter","initialCount="+initialCount);
  29. if (true) {
  30. screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
  31. return;
  32. }
  33. //E
  34. if (initialCount <= 0) {
  35. return;
  36. }
  37. screen.setInitialExpandedChildrenCount(initialCount);
  38. }

Android9.0 Settings 修改踩坑记录的更多相关文章

  1. XXLJOB2.1.0数据源配置踩坑记录

    最近在看XXLJOB,因为截至到发文时间最新的版本是2.1.0而且需要建立的数据库与Quartz解耦了,所以就用了最新的版本. 首先说一下踩坑过程: 代码开发完成之后,在定时跑的时候第一次跑的多数失败 ...

  2. 【原创】SpringBoot 2.7.0通过lettuce及commons-pool2 v2.9.0集成Redis踩坑记录

    背景 公司的一个项目由于HTTPS证书到期,导致小程序.POS不能正常使用.所以百度了下,通过URL检测证书有效期的代码,并自行整合到一个服务中. 代码仓库:[基于SpringBoot + 企业微信 ...

  3. manjaro xfce 18.0 踩坑记录

    manjaro xfce 18.0 踩坑记录 1 简介1.1 Manjaro Linux1.2 开发桌面环境2 自动打开 NumLock3 系统快照3.1 安装timeshift3.2 使用times ...

  4. HDP 3.1.0 集成 Sqoop2 踩坑问题记录

    HDP 3.1.0 集成 Sqoop2 踩坑问题记录 本文原始地址:https://sitoi.cn/posts/65261.html 问题一 $ sqoop:000> start job -n ...

  5. CentOS7.4安装MySQL踩坑记录

    CentOS7.4安装MySQL踩坑记录 time: 2018.3.19 CentOS7.4安装MySQL时网上的文档虽然多但是不靠谱的也多, 可能因为版本与时间的问题, 所以记录下自己踩坑的过程, ...

  6. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  7. 复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

    从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负责的模块connector就派上了用场. ...

  8. python发布包到pypi的踩坑记录

    前言 突然想玩玩python了^_^ 这篇博文记录了我打算发布包到pypi的踩坑经历.python更新太快了,甚至连这种发布上传机制都在不断的更新,这导致网上的一些关于python发布上传到pypi的 ...

  9. 使用Windows下的git工具往github上传代码 踩坑记录

    使用Windows下的git工具往github上传代码 踩坑记录 背景 由于以前接触的项目都是通过svn进行版本控制,现在公司项目使用git,加上自己平时有一个练手小项目,趁着周末试着把项目上传到自己 ...

随机推荐

  1. 3、python第三方库的安装方式

    在学习Python过程中,经常要用到很多第三方库,面对各种不同情况,Python为我们提供了多种安装方法,这里主要介绍三种 方法:pycharm在线安装.pip在线安装(强烈推荐).离线安装. 方式一 ...

  2. Excel.Application class

    https://docs.microsoft.com/en-us/javascript/api/excel/excel.application?view=office-js Represents th ...

  3. python3中的RE(正则表达式)

    记录大佬的 整理 原文来自:https://blog.csdn.net/weixin_40136018/article/details/81183504 1.引入正则模块(Regular Expres ...

  4. [校内训练19_09_02]C

    题意 给出一棵N 个节点的树,树上的每个节点都有一个权值$a_i$. 有Q 次询问,每次在树上选中两个点u, v,考虑所有在简单路径u, v 上(包括u, v)的点构成的集合S. 求$\sum_{w∈ ...

  5. Nginx核心模块

    error_log 语法:error_log file [ debug | info | notice | warn | error | crit ]默认值:${prefix}/logs/error. ...

  6. pycharm2019破解

    pycharm2019 2破解教程 参考这个方法 https://www.cnblogs.com/liuyanhang/p/11088167.html

  7. 【WPF学习】第三十六章 样式基础

    前面三章介绍了WPF资源系统,使用资源可在一个地方定义对象而在整个标记中重用他们.尽管可使用资源存储各种对象,但使用资源最常见的原因之一是通过他们的保存样式. 样式是可应用于元素的属性值集合.WPF样 ...

  8. 基于TensorFlow的MNIST手写数字识别-初级

    一:MNIST数据集    下载地址 MNIST是一个包含很多手写数字图片的数据集,一共4个二进制压缩文件 分别是test set images,test set labels,training se ...

  9. 目标检测之RCNN,fast RCNN,faster RCNN

    RCNN: 候选区生成(Selective Search). 分割成2000左右的候选小区域 合并规则:颜色.纹理相近,尺度均匀,合并后形状规则 特征提取. 归一候选区尺寸为227×227,归一方法. ...

  10. 使用sass语法生成自己的css的样式库

    前言 先说一下 sass 和 scss的区别 sass 是一种缩进语法(即没有花括号和分号,只使用换行 缩进的方式去区别子元素,PS:这是我个人的理解) scss 是css-like语法  (它的语法 ...