ベースとなるアプリの設定画面を作ろうと色々調べて、Preferenceを使うと良い…というのはわかった。
が、サンプルの内容をそのまま使おうとしたら非推奨のメソッドになっていたり…と難航。
その結果、Android Studioのテンプレートから設定Activityを作って、いらない部分を消していく事にしたが、非推奨のActivityやFragmentはそのままでとりあえず動かせるようにする。
テンプレートでは2階層の構成(Headersから更に選択→設定項目表示)になっていたが、今回は設定項目が少ないので1階層にしたくて最小まで削った内容。
※Android Studio上の操作は、日本語化しているので項目も翻訳版で表記
【前提】MainActivityから1階層の設定画面を呼び出す
①PreferenceのXMLを作る
・string.xmlに設定項目を記述しておく
app>src>main>res>values>「string.xml」
・app>src>main>resに「xml」フォルダを作る
新規>ディレクトリー>名前に「xml」を入力してOK
・「xml」フォルダ内に「〇〇〇.xml」(例:preference.xml)を作る
新規>XML リソース・ファイル>小文字で任意の名前を入力してOK
・XMLファイル内に設定項目を記述
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="@string/pre_title"> <PreferenceCategory android:title="@string/pre_agrouptitle"> <EditTextPreference android:id="@+id/prea1" android:key="@string/pre_a1key" android:title="@string/pre_a1title" android:inputType="numberDecimal" android:maxLength="5" android:defaultValue="@string/pre_a1dval" /> <EditTextPreference android:id="@+id/prea2" android:key="@string/pre_a2key" android:title="@string/pre_a2title" android:inputType="number" android:maxLength="3" android:defaultValue="@string/pre_a2dval" /> </PreferenceCategory> <PreferenceCategory android:title="@string/pre_bgrouptitle"> <SwitchPreference android:key="@string/pre_b1key" android:defaultValue="@string/pre_b1dval" ←ここはtrue、falseを指定 android:title="@string/pre_b1title" /> </PreferenceCategory> </PreferenceScreen>
上記ではEditTextPreference(入力項目)とSwitchPreference(On/Off)だけを記述したが、他にも色々あるので内容は当記事の最下部の参考資料を参照。
②PreferenceActivityを作る
・app>src>main>java>パッケージ名の中に新規Classを作る(例:SettingsActivity)
新規>Java クラス>任意の名前を入力してOK(入力規則では UpperCamelCase のようにする)
・中身は下記の内容を記述
public class SettingsActivity extends PreferenceActivity { // 画面上部に←ボタンを表示 private void setupActionBar() { ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { // Show the Up button in the action bar. actionBar.setDisplayHomeAsUpEnabled(true); } } // ←を押されたら @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { // このActivity終了でMainActivityに戻る finish(); return true; } return super.onOptionsItemSelected(item); } // ソフトウェア戻るボタン @Override public void onBackPressed() { // このActivity終了でMainActivityに戻る finish(); } // 設定項目の内容を変更された場合の処理 private Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object value) { String stringValue = value.toString(); preference.setSummary(stringValue); return true; } }; // 設定項目のサマリーに現在の設定値を表示 private void bindPreferenceSummaryToValue(Preference preference) { preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, PreferenceManager .getDefaultSharedPreferences(preference.getContext()) .getString(preference.getKey(), "")); } // Activity生成時の処理 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setupActionBar(); // 設定画面を表示 getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingsFragment()) .commit(); } // Fragmentのチェック protected boolean isValidFragment(String fragmentName) { return SettingsFragment.class.getName().equals(fragmentName); } @SuppressLint("ValidFragment") // これを入れないとclass作成できない。 public class SettingsFragment extends android.preference.PreferenceFragment { // ここで作成したpreference.xmlを読込 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); setHasOptionsMenu(true); // 設定項目のサマリーに現在の設定値を反映 ... b2はスイッチなのでサマリーなし bindPreferenceSummaryToValue(findPreference(getString(R.string.pre_a1key))); bindPreferenceSummaryToValue(findPreference(getString(R.string.pre_a2key))); } } // ←ボタンを表示するアクションバーの操作 private AppCompatDelegate mDelegate; public ActionBar getSupportActionBar() { return getDelegate().getSupportActionBar(); } private AppCompatDelegate getDelegate() { if (mDelegate == null) { mDelegate = AppCompatDelegate.create(this, null); } return mDelegate; } }
③ManifestにActivityを追加
・app>src>mainの「AndroidManifest.xml」を編集する
<application>タグの中に下記を追記
<!-- 設定Activity --> <activity android:name=".SettingsActivity" android:label="@string/pre_title" />
④MainActivityからPreferenceActivityを呼出
・呼び出したい箇所で下記の内容を記述
Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent);
startActivityで呼び出してるので、設定Activityを終了させるときはfinish()で良い。
⑤その他
設定項目にEditTextPreferenceがあるため内容をチェックしたい。
この内容については長くなるので別の記事で。
【参考資料】
PreferenceActivity/PreferenceFragmentを使った設定画面 → https://qiita.com/phicdy/items/f7ca6df0cc458e7550fb
Support7Demos(記事下の追記部分に@SuppressLint(“ValidFragment”)についての記載) → http://www.globefish.jp/wp/2013/07/support7demos.html
【おまけ】
Android Studioのテンプレートから作成したPreferenceは画面の大きさによって表示が変わる。
全2階層で構成されている設定画面で8インチ未満は1階層ずつ順番に表示されるけど、8インチ以上のタブレットサイズだと↓な感じ。カスタマイズすればスマホサイズでもできそう。