上圖展現的很清楚,當系統語言爲中文時,PreferenceScreen 中的摺疊項 summary 描述重複顯示的 bug,系統語言爲英文時正常。java
先搜索 當前顯示了 字符串,還真找到了android
prebuilts\sdk\current\support\v7\preference\res\values-zh-rCN\values-zh-rCN.xmlsegmentfault
<?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,又找到以下的地方app
看着 androidTest 相關的能夠忽略,直接看 CollapsiblePreferenceGroupController.java
frameworks\support\preference\src\main\java\androidx\preference\CollapsiblePreferenceGroupController.javaide
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 依舊,而後又繼續搜索,ui
在 out 目錄下還發現了另外一個 當前顯示了 字符串,文件內容和 prebuilts 下的是如出一轍的,可是文件時間倒是 2018-05-25 06:04google
這就很詭異了,感受此路不通啊,那好吧,乖乖去捋一捋源碼吧.net
通過簡單的分析,找到 Settings 中的 HighlightablePreferenceGroupAdapter 類code
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
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); }