Android9.0 Settings 修改踩坑记录

问题现象

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

修改历程

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

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

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:ns1="urn:oasis:names:tc:xliff:document:1.2">
    <string msgid="3265458434114353660" name="expand_button_title">"高级"</string>
    <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>
    <string msgid="2082379519172883894" name="v7_preference_off">"关闭"</string>
    <string msgid="7922757586228621900" name="v7_preference_on">"开启"</string>
</resources>

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

看着 androidTest 相关的可以忽略,直接看 CollapsiblePreferenceGroupController.java
frameworks\support\preference\src\main\java\androidx\preference\CollapsiblePreferenceGroupController.java

private void setSummary(List<Preference> collapsedPreferences) {
            CharSequence summary = null;
            final List<PreferenceGroup> parents = new ArrayList<>();

            for (Preference preference : collapsedPreferences) {
                final CharSequence title = preference.getTitle();
                if (preference instanceof PreferenceGroup && !TextUtils.isEmpty(title)) {
                    parents.add((PreferenceGroup) preference);
                }
                if (parents.contains(preference.getParent())) {
                    if (preference instanceof PreferenceGroup) {
                        parents.add((PreferenceGroup) preference);
                    }
                    continue;
                }
                if (!TextUtils.isEmpty(title)) {
                    if (summary == null) {
                        summary = title;
                    } else {
                        summary = getContext().getString(
                                R.string.summary_collapsed_preference_list, summary, title);
                    }
                }
            }
            setSummary(summary);
        }

哈,这下证实了 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

import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceGroupAdapter;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;

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


LOCAL_STATIC_ANDROID_LIBRARIES :=     android-slices-builders     android-slices-core     android-slices-view     android-support-compat     android-support-v4     android-support-v13     android-support-v7-appcompat     android-support-v7-cardview     android-support-v7-preference     android-support-v7-recyclerview     android-support-v14-preference \

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

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

Android.mk


LOCAL_STATIC_ANDROID_LIBRARIES :=     androidx-constraintlayout_constraintlayout     androidx.slice_slice-builders     androidx.slice_slice-core     androidx.slice_slice-view     androidx.core_core     androidx.appcompat_appcompat     androidx.cardview_cardview     androidx.preference_preference     androidx.recyclerview_recyclerview     com.google.android.material_material     setupcompat     setupdesign

解决办法

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

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

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

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

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

public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        mPreferenceList = new ArrayList<>();

        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);

        mOrderingAsAdded =
                TypedArrayUtils.getBoolean(a, R.styleable.PreferenceGroup_orderingFromXml,
                        R.styleable.PreferenceGroup_orderingFromXml, true);

        if (a.hasValue(R.styleable.PreferenceGroup_initialExpandedChildrenCount)) {
            setInitialExpandedChildrenCount((TypedArrayUtils.getInt(
                    a, R.styleable.PreferenceGroup_initialExpandedChildrenCount,
                    R.styleable.PreferenceGroup_initialExpandedChildrenCount, Integer.MAX_VALUE)));
        }
        a.recycle();
    }

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

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

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

/**
     * Tries to override initial expanded child count.
     * <p/>
     * Initial expanded child count will be ignored if:
     * 1. fragment contains request to highlight a particular row.
     * 2. count value is invalid.
     */
    public static void adjustInitialExpandedChildCount(SettingsPreferenceFragment host) {
        Log.e("HighlightablePreferenceGroupAdapter"," adjustInitialExpandedChildCount()");
        if (host == null) {
            return;
        }
        final PreferenceScreen screen = host.getPreferenceScreen();
        if (screen == null) {
            return;
        }
        final Bundle arguments = host.getArguments();
        if (arguments != null) {
            final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY);
            if (!TextUtils.isEmpty(highlightKey)) {
                // Has highlight row - expand everything
                screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
                return;
            }
        }

        final int initialCount = host.getInitialExpandedChildCount();
        //cczheng add for expand everything preference S
        Log.e("HighlightablePreferenceGroupAdapter","initialCount="+initialCount);
        if (true) {
            screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
            return;
        }
        //E
        if (initialCount <= 0) {
            return;
        }
        screen.setInitialExpandedChildrenCount(initialCount);
    }

原文地址:https://www.cnblogs.com/cczheng-666/p/12092838.html

时间: 2024-10-11 13:40:19

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

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

最近在看XXLJOB,因为截至到发文时间最新的版本是2.1.0而且需要建立的数据库与Quartz解耦了,所以就用了最新的版本. 首先说一下踩坑过程: 代码开发完成之后,在定时跑的时候第一次跑的多数失败,报的错是:Communications link failure 上网搜了一下说是MySQL数据库连接时间超过八小时就会断开需要加一些配置,或者把数据库的时间延长.原先用的数据源是Druid,所以就把网上找到的代码加到数据源配置上,同时延长了MySQL的链接持续时间,问题依然没有解决. 一次偶然的

IDFA踩坑记录

IDFA踩坑记录: 1.iOS10.0 以下,即使打开"限制广告跟踪",依然可以读取idfa: 2.打开"限制广告跟踪",然后再关闭"限制广告跟踪",idfa会改变: 3.越狱机器安装开发证书打的包,读取的idfa正常: 4.越狱机器安装本地打的发布证书的包,读取idfa异常,第一次打开app读取的是一个错误的idfa,第二次打开会变成另外一个错误的idfa: 5.越狱机器安装Testflight的包,读取idfa异常,第一次打开app读取的是一

unionId突然不能获取的踩坑记录

昨天(2016-2-2日),突然发现系统的一个微信接口使用不了了.后来经查发现,是在网页授权获取用户基本信息的时候,unionid获取失败导致的. 在网页授权获取用户基本信息的介绍中(http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html),unionid可以在第二步(https://api.weixin.qq.com/sns/oauth2/access_token)和第四步的2个接口中获得.其中,第四步的接口是

【Pysc2】Deepmind Pysc2 环境配置及其踩坑记录

1. 下载星际争霸II游戏 可以直接下暴雪战网,然后在战网内下载. 2. 下载Pysc2 cmd后在命令行输入 pip install pysc2 3. 下载sc2 cmd后在命令行输入 pip install sc2 4. 下载地图 https://github.com/ClausewitzCPU0/SC2AI 解压密码: iagreetotheeula (表示自己同意最终用户许可协议) 解压在Maps的文件夹,我是使用的暴雪战网下载的游戏,发现游戏文件夹里并没有Maps, 需要自己手动创建.

Linux Git 踩坑记录

Linux Git 踩坑记录 git cherry-pick 冲突解决 出现: error: could not apply xxxxxx(commit ID)... ***** hint: after resolving the conflicts, mark the corrected paths hint: with 'git add ' or 'git rm ' hint: and commit the result with 'git commit' 此时使用git status命令查

vue2.0 踩坑记录之组件

- did you register the component correctly? For recursive components, make sure to provide the "name" option. 出现如上错误的原因大致有以下三点(我踩坑只踩到了这四种情况,如果还有 之后会更新) 1.未能正确的拼好components单词. 这是个低级错误,应该作为第一步排查的可能 2.定义子组件时没有在父组件的内部定义 子组件一定要在父组件中局部注册 3.局部注册的定义写在了实

微信小程序之蓝牙 BLE 踩坑记录

前言 前段时间接手了一个微信小程序的开发,主要使用了小程序在今年 3 月开放的蓝牙 API ,此过程踩坑无数,特此记录一下跳坑过程.顺便开了另一个相关的小项目,欢迎 start 和 fork: BLE_MiniProgram API简介 微信小程序目前有蓝牙 API 共 18 个,其中操作蓝牙适配器的共有 4 个,分别是 wx.openBluetoothAdapter 初始化蓝牙适配器 wx.closeBluetoothAdapter 关闭蓝牙模块 wx.getBluetoothAdapterS

CISCO配置文件的导出和导入(Timed out)问题 踩坑记录

起因: 我:这台交换机我要用. 武哥:不行,在测试,上面很多配置项都不能动! 我..... 后来武哥找了台3560交换机让我自己玩去:"拷贝一下交换机配置,就能用了" 使用工具:3CDaemon 大致流程: 1 开启3CDaemon,这样你的电脑就能作为一个tftp服务器了,监控udp 69端口 2 交换机配置文件拷贝到tftp上 #copy   源   目的: 输入tftp服务器地址 确定文件名(如果是交换机从tftp下载要输入文件名) ok 简单so 3 将tftp服务器上的配置文

canvas 踩坑记录

一.绘制一个带有多张图片和文字的canvas.要求将一张矩形的图片,放置进去显示为圆角矩形的图片 解决方案,先把图片处理成圆角矩形的样子,再放进去就可以了 绘制圆角矩形图片的解决方案 <img src="http://pics.sc.chinaz.com/files/pic/pic9/201505/apic11973.jpg" width="400" /> <!--canvas的默认画布大小为300×150--> <canvas id=