我开始百度找轮子,得知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忘了同步仍是写错了?