Android9.0 Settings 修改踩坑记录

简介: Android9.0 Settings 修改踩坑记录

问题现象


aHR0cHM6Ly9zMi5heDF4LmNvbS8yMDE5LzExLzEyL00zZVlmcy5wbmc.png

上图展示的很清楚,当系统语言为中文时,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,又找到如下的地方

aHR0cHM6Ly9zMi5heDF4LmNvbS8yMDE5LzExLzEyL00zWU9pdC5wbmc.png


看着 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


aHR0cHM6Ly9zMi5heDF4LmNvbS8yMDE5LzExLzEyL00zVWk4MC5wbmc.png

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


经过简单的分析,找到 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

aHR0cHM6Ly9zMi5heDF4LmNvbS8yMDE5LzExLzEyL00zYVJtRC5wbmc.png

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);
    }


目录
相关文章
|
7月前
|
Java 测试技术 Android开发
Android Gradle 干货,看这篇文章就行了
Android Gradle 干货,看这篇文章就行了
|
Java Android开发 Kotlin
AndroidQ(10.0) SystemUI 修改踩坑汇总
AndroidQ(10.0) SystemUI 修改踩坑汇总
472 0
|
XML Android开发 数据格式
Android 10.0 Settings 加载流程(一)
Android 10.0 Settings 加载流程(一)
|
Java Maven 开发工具
Android Gradle 2.3.3 升级 3.0.1 小记录
整理 Android Gradle 升级过程中小问题!
1062 0
|
Android开发
Android 面试(六):你已经用 SharedPrefrence 的 apply() 替换 commit() 了吗?
这是 面试系列 的第六期。本期我们将来探讨一个有趣的东西 —— SharePrefrence 的两种提交方式 apply() 和 commit()。 往期内容传递:Android 面试(一):说说 Android 的四种启动模式Android 面试(...
1474 0
|
缓存 Android开发 开发工具
|
Android开发
Android 下载apk提示更新以及解决Android 6.0 Marshmallow提示更新报错问题
下载并安装apk的方法很多,但是谷歌还是建议我们采用DownloadManager。 下载更新的代码比较简单,分如下几块: 启动下载 public long startDownload(String uri, St...
1512 0