PreferenceActivityって便利でしたよね
XMLで設定項目を定義することで簡単に設定画面を作ることができます。API Level 15では直接設定画面を作ることがdeprecatedになった後もPreferenceFragmentと組み合わせて使われていました。しかし、ついにAPI Level 29にてdeprecatedになってしまいました。
FragmentのほうはPreferenceFragmentCompatがAndroidXで提供されていますが、PreferenceActivityの代替手段は提供されていません。
無いのなら作ってしまえばいいということで(少し前に)作りました。PreferenceActivityCompat
です。
jCenterに登録していますので以下だけでつかえます。
implementation 'net.mm2d:preference:0.1.2'
Android 4.x上でもマテリアルデザインが適用されます。
PreferenceActivity | PreferenceActivityCompat |
---|---|
![]() |
![]() |
元々のPreferenceActivtyの全機能をサポートしているわけではなく、preference-headers
を定義してPreferenceFragment
を呼び出していたところを、PreferenceFragmentCompat
を呼び出せるようにしたものです。
また、実際の設定項目などの部分はPreferenceFragmentCompat
にお任せで、PreferenceFragmentCompat
自体の改善を行うものではありません。
使い方
少し前まで、Android StudioでSettings Activityを作成すると勝手に作られていたAppCompatPreferenceActivity
を使った設定画面を拙作のPreferenceActivityCompat
に置き換えるという形で説明していきます。(ほぼReadmeの翻訳)
1. preferenceTheme
をPreferenceActivity
のテーマに追加
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
+ <item name="preferenceTheme">@style/PreferenceCompatTheme</item>
</style>
2. SettingsActivity
の親クラスを書き換え
- public class SettingsActivity extends AppCompatPreferenceActivity {
+ public class SettingsActivity extends PreferenceActivityCompat {
isValidFragment
がprotected
で定義されていると思いますので、public
に書き換えます。
@Override
- protected boolean isValidFragment(final String fragmentName) {
+ public boolean isValidFragment(final String fragmentName) {
onMenuItemSelected
をOverrideしている場合は、onOptionsItemSelected
に書き換えます。
@Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ public boolean onOptionsItemSelected(final MenuItem item) {
final int id = item.getItemId();
if (id == android.R.id.home) {
- if (!super.onMenuItemSelected(featureId, item)) {
+ if (!super.onOptionsItemSelected(item)) {
NavUtils.navigateUpFromSameTask(this);
}
return true;
}
- return super.onMenuItemSelected(featureId, item);
+ return super.onOptionsItemSelected(item);
}
3. PreferenceFragment
をPreferenceFragmentCompat
に書き換え
onCreate
で書いていた処理はonCreatePreferences
に書き換えます。
- public static class GeneralPreferenceFragment extends PreferenceFragment {
+ public static class GeneralPreferenceFragment extends PreferenceFragmentCompat {
@Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ public void onCreatePreferences(final Bundle savedInstanceState,final String rootKey) {
addPreferencesFromResource(R.xml.native_pref_general);
}
4. インポートの書き換え
android.preference.PreferenceActivity.Header
をnet.mm2d.preference.Header
に置き換えます。
- import android.preference.PreferenceActivity.Header;
+ import net.mm2d.preference.Header;
android.preference
をandroidx.preference
に書き換えます。
- import android.preference.ListPreference;
- import android.preference.Preference;
- import android.preference.Preference.OnPreferenceChangeListener;
- import android.preference.PreferenceFragment;
- import android.preference.PreferenceManager;
+ import androidx.preference.ListPreference;
+ import androidx.preference.Preference;
+ import androidx.preference.Preference.OnPreferenceChangeListener;
+ import androidx.preference.PreferenceFragmentCompat;
+ import androidx.preference.PreferenceManager;
5. xmlのnamespaceの書き換え
preference-headers
を定義しているxmlのnamespaceをandroid
からapp
に書き換えます。
<preference-headers
- xmlns:android="http://schemas.android.com/apk/res/android">
+ xmlns:app="http://schemas.android.com/apk/res-auto">
<header
- android:fragment="net.mm2d.preference.sample.SettingsActivity$GeneralPreferenceFragment"
- android:icon="@drawable/ic_info_black_24dp"
- android:title="@string/pref_header_general"
+ app:fragment="net.mm2d.preference.sample.SettingsActivity$GeneralPreferenceFragment"
+ app:icon="@drawable/ic_info_black_24dp"
+ app:title="@string/pref_header_general"
/>
6. SwtichPreference
をSwitchPreferenceCompat
に書き換え(必要なら)
PreferenceFragmentCompat
では置き換え可能というだけなので、PreferenceActivityCompat
は関係無いです。
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <SwitchPreference
+ <!--suppress AndroidElementNotAllowed -->
+ <SwitchPreferenceCompat
android:defaultValue="true"
android:key="example_switch"
android:summary="@string/pref_description_social_recommendations"
android:title="@string/pref_title_social_recommendations"
/>
なぜ置き換えるか、というと、Android 4.4 以前ではSwitchPreferenceのままではマテリアルデザインにならないからです。
SwitchPreference | SwitchPreferenceCompat |
---|---|
![]() |
![]() |
ただ、警告が出ちゃうのが美しくないです
7. アイコン用のmarginが不要ならapp:iconSpaceReserved="false"
を追加
こちらもPreferenceFragmentCompat
を使う上での話でPreferenceActivityCompat
は関係無いです。
<Preference
android:title="@string/pref_title_system_sync_settings"
+ app:iconSpaceReserved="false"
>
デフォルトでアイコン分の余白が出るようになっちゃったんですよね。app:iconSpaceReserved="false"
で詰めることができます。
default | app:iconSpaceReserved="false" |
---|---|
![]() |
![]() |
まとめ
かつてのPreferenceActivityを延命させられるかもしれないライブラリを作ってみたというご紹介でした。