Written by https://xisberto.wordpress.com/2014/11/08/how-to-combine-actionbar-and-preferenceactivity-headers-with-appcompat/
How to combine ActionBar and PreferenceActivity headers with AppCompat
Update: This is deprecated. Use the new AppCompatDelegate, it’s way better and easier. Follow the instructions on the Android Developers blog.
Since the introduction of the Support libraries on Android, PreferenceActivity was kept apart, and its new APIs didn’t receive support for older Android versions. Currently, to create a Preferences screen, you have to:
- Use the new PreferenceFragment for the newer versions
- Use the old addPreferencesFromResource for the older versions
- Keep a XML emulating the headers for the older versions
This lead to a situation where you had almost the complete functionality, but no ActionBar for the older versions, and two Activities to handle this.
I was satisfied with the situation, but found some problems with the headers. Then I found this answer on a StackOverflow thread. The trick with the Toolbar worked, and then I take a further step and improved it.
There’s a Github project with this code, I will put some exerts here.
Extend PreferenceActivity
You will create a class extending PreferenceActivity. This will be the only Activity you will need for your Preferences. During the onCreate, apply the solution from the StackOverflow linked above:
ViewGroup root = (ViewGroup) findViewById(android.R.id.content); View content = root.getChildAt(0); LinearLayout toolbarContainer = (LinearLayout) View.inflate(this, R.layout.activity_prefs, null); root.removeAllViews(); toolbarContainer.addView(content); root.addView(toolbarContainer);
What this code does:
- Gets a reference to the Activity’s content (android.R.id.content)
- Inflates a layout made of a LinearLayout and a Toolbar (from the appcompat support library)
- Removes all views from the root view
- Adds the Activity’s content (android.R.id.content) to the inflated layout
- Adds the inflated layout to the root view
After this, we can
Setup the Toolbar
mToolBar = (Toolbar) toolbarContainer.findViewById(R.id.toolbar); mToolBar.setTitle(getTitle()); mToolBar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha); mToolBar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } });
This code set the Toolbar title to the Activiy’s title and adds a up navigation icon that finishes the Activity. The drawable used is part of the appcompat library.
Setup the PreferenceFragment
We can configure the PreferenceFragment as explained on the API Guides, and make it load the preferences screens according to the Extra defined on the header’s XML.
res/xml/headers.xml:
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> <header android:title="@string/header_general" android:fragment="net.xisberto.preferencescompat.PrefsFragment" > <extra android:name="category" android:value="category_general" /> </header> <header android:title="@string/header_advanced" android:fragment="net.xisberto.preferencescompat.PrefsFragment" > <extra android:name="category" android:value="category_advanced" /> </header> </preference-headers>
src/net.xisberto.preferencescompat/PrefsFragment.java:
@TargetApi(Build.VERSION_CODES.HONEYCOMB) public class PrefsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String category = getArguments().getString("category"); if (category != null) { if (category.equals(getString(R.string.category_general))) { addPreferencesFromResource(R.xml.prefs_general); } else if (category.equals(getString(R.string.category_advanced))) { addPreferencesFromResource(R.xml.prefs_advanced); } } } }
.
Adding support to older versions
For the versions before Honeycomb (3.0), we use the PreferenceActivity’s addPreferencesFromResource. This will be marked as deprecated, but it’s ok.
This code can be called during the Activity’s OnCreate method.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { String action = getIntent().getAction(); if (action == null) { addPreferencesFromResource(R.xml.headers_legacy); } else if (action.equals(getString(R.string.category_general))) { mToolBar.setTitle(getString(R.string.header_general)); addPreferencesFromResource(R.xml.prefs_general); } else if (action.equals(getString(R.string.category_advanced))) { mToolBar.setTitle(getString(R.string.header_general)); addPreferencesFromResource(R.xml.prefs_advanced); } }
This code analyses the Action posted to the Activity. A null Action will show a PreferenceScreen that emulates the preference-headers above, with Preferencesthat call Intents.
Final Toughts
On tablets, the selected header will be colored according to the colorAccentdefined on your theme extending Theme.AppCompat. Look at the styles.xml for a very simple theme.
This code lets two things unresolved:
- There’s no shadow on the Toolbar. This can be resolved on the activity_prefs layout.
- On pre-Honeycomb tablets (there are a few of them), will be no two-pane layout, since the legacy code doesn’t support it.
If you need another explanation don’t be afraid of commenting, but take also a time to look on the Github project.
'모바일개발(Mobile Dev) > 안드로이드개발(Android)' 카테고리의 다른 글
About PreferenceFragment with Toolbar (0) | 2016.10.01 |
---|---|
PrefereceActivity SubActivity with Back Button (arrow) (0) | 2016.09.25 |
about status bar transparency (0) | 2016.09.15 |
Android UI : Fixing skipped frames (0) | 2016.09.11 |
android upload example (0) | 2016.09.09 |