Android9.0 Settings 修改踩坑记录

2024-08-22 06:32

本文主要是介绍Android9.0 Settings 修改踩坑记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题现象

M3eYfs.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,又找到如下的地方

M3YOit.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

M3Ui80.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

M3aRmD.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

<PreferenceScreenxmlns: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 everythingscreen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);return;}}final int initialCount = host.getInitialExpandedChildCount();//cczheng add for expand everything preference SLog.e("HighlightablePreferenceGroupAdapter","initialCount="+initialCount);if (true) {screen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);return;}//E if (initialCount <= 0) {return;}screen.setInitialExpandedChildrenCount(initialCount);}

这篇关于Android9.0 Settings 修改踩坑记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095505

相关文章

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

Python UV安装、升级、卸载详细步骤记录

《PythonUV安装、升级、卸载详细步骤记录》:本文主要介绍PythonUV安装、升级、卸载的详细步骤,uv是Astral推出的下一代Python包与项目管理器,主打单一可执行文件、极致性能... 目录安装检查升级设置自动补全卸载UV 命令总结 官方文档详见:https://docs.astral.sh/

统一返回JsonResult踩坑的记录

《统一返回JsonResult踩坑的记录》:本文主要介绍统一返回JsonResult踩坑的记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录统一返回jsonResult踩坑定义了一个统一返回类在使用时,JsonResult没有get/set方法时响应总结统一返回

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、