我開始百度找輪子,得知android10使用androidx全面替代,看了一下遷移的對應關係migrate,因而又百度androidx.preference,但結果寥寥無幾,只有androidx PreferenceDialogFragmentCompat 和 DialogPreference的配合應用這一篇有一些記載,但對於咱們這樣的菜鳥很不友好,沒有講基礎的使用方法或貼代碼,裏面的參考文檔還被牆打不開。html
不得已去看官方API,終於找到了使用方法指南,居然有中文!!!還這麼簡潔,我大喜過望,趕忙上手操做java
implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.core:core:1.2.0-beta01' implementation 'androidx.fragment:fragment:1.2.0-rc01'
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/> <Preference app:key="feedback" app:title="Send feedback" app:summary="Report technical issues or suggest new features"/> </PreferenceScreen>
public class MySettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.preferences, rootKey); } }
public class MySettingsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportFragmentManager() .beginTransaction() .replace(R.id.settings_container, new MySettingsFragment()) .commit(); } }
首先是沒有了header的方式,但個人APP暫時仍是須要這種佈局,因而用RecyclerView模擬了一個android
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:orientation="vertical" android:paddingStart="15dp" android:paddingTop="10dp" android:paddingEnd="15dp" android:paddingBottom="10dp"> <!--actionBarItemBackground --> <TextView android:id="@+id/activity_settings_label" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAllCaps="true" android:textStyle="bold" android:textAppearance="@style/TextAppearance.AppCompat.Medium" /> <TextView android:id="@+id/activity_settings_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Small" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:id="@+id/activity_settings_layout" android:layout_height="match_parent" android:orientation="vertical"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/activity_settings_recyclerv" android:layout_width="match_parent" android:layout_height="match_parent" /> <FrameLayout android:id="@+id/activity_settings_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
這裏偷了個懶,用顯示隱藏RecycerView的方式來給Fragment騰地方git
因爲PreferenceScreen還要用Fragment顯示, 因而在AppCompatActivity中用recyclerview來觸發事件顯示fragmentgithub
headers.add(new SettingHeader("應用", "配置應用主題、會話", new SettingFragment(R.xml.settings_app))); headers.add(new SettingHeader("編輯器", "配置編輯器、代碼、保存", new SettingFragment(R.xml.settings_editor))); headers.add(new SettingHeader("構建、運行", "配置工程構建和運行設置", new SettingFragment(R.xml.settings_build))); headers.add(new SettingHeader("關於", "介紹等", new SettingFragment(R.xml.settings_about))); recyclerv.setAdapter(new BaseRecyclerAdapter<SettingHeader>(headers) { @Override protected int getItemLayoutId(int viewType) { return R.layout.activity_settings_item; } @Override protected void bindData(@NonNull RecyclerViewHolder holder, int position, SettingHeader item) { holder.getTextView(R.id.activity_settings_label).setText(item.label); holder.getTextView(R.id.activity_settings_message).setText(item.message); holder.itemView.setOnClickListener(v -> { getSupportFragmentManager() .beginTransaction() .replace(R.id.activity_settings_container, item.fragmentCompat) .commit(); recyclerv.setVisibility(View.GONE); }); } }); recyclerv.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
爲了減小代碼,我機智地複用一個SettingFragment來加載不一樣xmlapp
public static class SettingHeader { public String label; public String message; public PreferenceFragmentCompat fragmentCompat; public SettingHeader(String label, String message, PreferenceFragmentCompat fragmentCompat) { this.label = label; this.message = message; this.fragmentCompat = fragmentCompat; } } public static class SettingFragment extends PreferenceFragmentCompat { private final int id; public SettingFragment(int xmlId) { super(); this.id = xmlId; } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(id, rootKey); } @Override public void onDisplayPreferenceDialog(Preference preference) { if (preference instanceof GenKeystorePreference) { ((GenKeystorePreference) preference).showDialog(); } else super.onDisplayPreferenceDialog(preference); } }
因而我滿懷信心地用AS跑了起來,一塊兒看起來是那麼地完美框架
沒問題,打開應用item編輯器
???這是什麼鬼ide
由於用到了一個換膚框架,有些兼容問題,起初我覺得是字體顏色和背景同樣,因而開始搗鼓主題,禁用框架,但毫無結果佈局
終於,機緣巧合之下,log提示我自定義的Preference有問題,DialogPreference再也不提供默認的新建Dialog操做,要經過onDisplayPreferenceDialog來設置,將其修復後log提示我沒有Preference have no Key!
但我明明有定義,徹底是按照官方的教程來的啊!思考半天,我嘗試用android:替換app:,最後運行以下
官方文檔有錯!本人記下了!!!
看這架勢應該是支持icon,預留了一個ImageView
官方文檔有錯,仍是用android:而不是app:,估計是升級lib忘了同步仍是寫錯了?