cause
- Possibly because of targetApi=29, AS reminded me that some of the methods in PreferenceActivity had been abandoned, and as a very radical amateur novice developer, my obsessive-compulsive disorder prompted me to find a solution
- Recent receipt of my small software AndroCode Some user feedback settings can not be opened at the second level, clicking does not respond
Find Wheel
I started Baidu looking for wheels, and learned that android10 uses androidx to completely replace, so I looked at the migration relationship migrate So Baidu androidx.preference, but the results are few, only Cooperative application of androidx PreferenceDialogFragmentCompat and DialogPreference This article has some records, but it is not friendly to rookies like us. It doesn't tell us how to use it or how to paste codes. The reference documents inside can't be opened by the wall.
Have to go Official API And finally find a way to use it guide There is Chinese!!!It's so concise, I'm glad to get started
Import Dependencyimplementation 'androidx.preference:preference:1.1.0' implementation 'androidx.core:core:1.2.0-beta01' implementation 'androidx.fragment:fragment:1.2.0-rc01'Official Demo
<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(); } }
First there was no header, but my APP still needed this layout for the time being, so I used RecyclerView to simulate one
activity_settings_item.xml<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>activity_settings.xml
<?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>
Here's a lazy steal to make room for Fragment s by showing hidden RecycerView s
Since PreferenceScreen also uses fragments to display, use recyclerview to trigger event display fragments in AppCompatActivity
onCreate:headers.add(new SettingHeader("application", "Configure application topics, sessions", new SettingFragment(R.xml.settings_app))); headers.add(new SettingHeader("editor", "Configuration Editor, Code, Save", new SettingFragment(R.xml.settings_editor))); headers.add(new SettingHeader("Build, run", "Configure project build and run settings", new SettingFragment(R.xml.settings_build))); headers.add(new SettingHeader("about", "Introduction, etc.", 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));
To reduce code, I intelligently reused a SettingFragment to load different xml
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); } }
So I ran with AS confidently and together it looked so perfect
No problem, open the application item
???What the ghost is this
Find the cause of the errorBecause of a skincare framework and some compatibility issues, I thought at first that the font color was the same as the background, so I started to mash up the theme, disable the frame, but nothing happened.
Finally, by chance, log prompted me that there was a problem with my custom Reference. Dialog Preference no longer provides the default new Dialog operation. Instead, set it by onDisplayPreferenceDialog, and after fixing it, log prompted me that I did not have a Preference have no Key!
But I clearly have a definition, and I'm just following the official tutorials!After half a day of thinking, I tried to replace app:, with android:
There is something wrong with the official document!I wrote it down!!!
Look at this gesture as supporting icon, reserving an ImageView
conclusion
Is there something wrong with the official documentation or with android: instead of app:, is it estimated that the upgrade lib forgot to sync or was written incorrectly?