リスナーの登録
XMLですべてのレイアウトを定義できますが、「値が変更された」「クリックされた」というリスナーは、コーディングしなければなりません。以下に1つ取り上げてみます。
// チェックボックス設定のインスタンスを、キーを基に取得する CheckBoxPreference cbp = (CheckBoxPreference)findPreference("checkbox_preference"); // リスナーを設定する cbp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { String summary; if (((Boolean)newValue).booleanValue()) { summary = "Selected"; } else { summary = "Unselected"; } // 更新された値に応じて概要を変更する ((CheckBoxPreference)preference).setSummary(summary); // 変更を適用するために true を返す return true; } });
設定を変更することで、以下のように概要が変化します。
XMLレイアウトで必要なコーディングは、基本的にこのリスナー登録だけです。今回のリスナーは「入力の状態に応じて概要を変更する」のみですが、実際には「入力チェックを行って、不正な入力の際には値を反映させない(falseを返す)」「リングトーン設定であれば、実際にデバイスの設定を変更する」などが行われます。
実際に動作させてみて気が付かれた方がいるかもしれませんが、リスナーは変更時に概要を設定し直すので、画面表示時には状態が分かりません。
このような場合はPreferenceManagerを使用して、現在の設定内容を取得します。PreferenceManagerの使い方は、この後すぐに解説します。
設定値を取得する
PreferenceActivityで設定された内容は、PreferenceActivityの表示時に自動的に読み込まれますが、設定された内容をアプリ本体で取得する場合は、PreferenceManagerとSharedPreferencesを使用します。
// 【1】デフォルトの SharedPreference を取得する SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); // 【2】設定内容をコミットする sp.edit().commit(); // 【3】設定内容をすべて取得する Map<String, ?> map = sp.getAll(); CharSequence[] list = new CharSequence[map.size()]; int i = 0; for (String key : map.keySet()) { list[i++] = key + "=" + map.get(key); }
【1】では、デフォルトのSharedPreferencesを取得しています。SharedPreferencesは、名前を付けて取得するメソッド「ContextWrapper#getSharedPreferences(String, int)」が用意されていて、このメソッドを使用する場合、以下の呼び出しが同じ動作になります。
getSharedPreferences("com.example.android.preference_preferences", MODE_PRIVATE);
デフォルトのSharedPreferencesの名前は、「パッケージ名_preference」というふうに決まっています。設定を初期化したい場合は、このファイルを削除すれば簡単に実現できます。1つのアプリで複数の設定を使用したい場合は、デフォルトを使用するのではなく、上記メソッドを使用して作成するとよいでしょう。作成する際に、第2引数に、定数「MODE_WORLD_READABLE」「MODE_WORLD_WRITEABLE」を指定してパーミッションをコントロールできます。
【2】では、SharedPreferencesのエディタを取得して、設定内容をコミットしています。SharedPreferencesは、永続化のためにストレージ上にファイルとして保存されますが、保存されるのはアプリが終了するタイミングで、それまではメモリ上に展開されています。ここでcommit()メソッドを呼び出しておくことで、メモリ上で変更された内容をストレージにコミットし、その内容を取得するようにしています。
【3】では、すべての設定項目をMapオブジェクトとして取得しています。個別にキーとデフォルト値を指定して値を取得するgetBoolean()、getFloat()、getInt()、getLong()、getString()が用意されているので、通常はこちらを使用します。
コンポーネントの依存関係を決めるには
しばしば設定項目には依存関係があるものもあります。例えばWi-Fiを使う場合はアクセスポイントの設定が必要ですが、Wi-Fiを使用しない場合はアクセスポイントの設定は不要です。
今回のアプリでは、以下のように動作します。
このような依存関係もXMLで簡単に定義できます。
【1】↓依存元の設定項目を定義 <CheckBoxPreference android:key="parent_checkbox_preference" android:title="@string/parent_preference_title" android:summary="@string/parent_preference_summary" /> <CheckBoxPreference android:key="child_checkbox_preference" 【2】↓依存元のキーを指定 android:dependency="parent_checkbox_preference" 【3】↓自動的に使用可・使用不可が切り替わるレイアウトを設定 android:layout="?android:attr/preferenceLayoutChild" android:title="@string/child_preference_title" android:summary="@string/child_preference_summary" />
親の設定項目を定義し、子の設定項目のandroid:dependencyに親のキーを、「android:layout」に「?android:attr/preferenceLayoutChild」を指定します。この設定を行うことで、「親がチェックされているときだけ子が使用できる」という動作が実現できます。
これをコーディングで行う場合、以下のようになります。
// 子設定を生成する際にonDependencyChangedをオーバーライド CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this) { @Override public void onDependencyChanged(Preference dependency, boolean disableDependent) { setEnabled(!disableDependent); } }; setPreferenceScreen(createPreferenceHierarchy()); // setPreferenceScreen が終わってから setDependency() を呼び出し getPreferenceManager().findPreference("child_checkbox_preference").setDependency("parent_checkbox_preference");
本来であれば、setDependency()というメソッドで依存関係を設定できますが、setLayoutResourceで設定するandroid.R.attr.preferenceLayoutChildが正常に機能しないため、期待通りの動作になりません(常に使用可能です)。ApiDemoのオリジナルのソースコードは別の不具合(setKey()が行われていない)がありますが、不具合を修正してもやはり期待通りに動作しません。
Androidのソースコードを検索してsetDependency()を使用している個所を確認したところ、使用しているすべてでXMLレイアウトの補助として使用されていることが分かり、XMLレイアウトで定義したファイルに対してsetDependency()を行ったところ、期待通りの動作になるため、これはもしかするとAndroidの不具合なのかもしれません。
上記の回避方法でも、まったく同様の動作ですが、XMLレイアウトは属性を2つ追加するだけなので、前述したとおりレイアウトはXMLで行うことを強く推奨します。
次回は、アニメーションで華やかな演出を
アプリに設定を持たせたい場合は、ごく簡単なものであればMenuなどでトグル状態を実装するなどの方法がありますが、いずれにせよ設定された値は永続化しなければならないため、その手間を考えるとPreferenceActivityを使うことは良い選択肢といえるでしょう。
次回はアニメーションで華やかな演出を行う方法について解説する予定です。
- グーグルのAPIを使うときに欠かせないGoogle OAuthの作り方と使い方
- 細か過ぎて伝わってないけど開発者が知っておきたいAndroid Mの新機能まとめ
- 腕時計から電話をかけるAndroid Wearアプリの作り方
- Android Wear用アプリの花形、時計アプリ「Watch Face」の基本的な作り方
- Android 5.0発表&スマホと連動する音声認識Android Wearアプリの作り方
- ウェアラブル端末用Android Wearアプリ開発の基礎知識
- 変わらないと生き残れないAndroid Lの新機能まとめ
- Android WearやIoTで注目のAndroidセンサー機能8選
- ウェアラブル時代に見直したいAndroidの加速度/重力センサー、ジャイロスコープ
- あなたの知らないAndroid SDKの便利tools、14選まとめ
- Android 4.4のメモリ使用状況を把握する3つのツールの使い方
- Androidでリアルタイムマルチプレーゲームを開発するには
- 低性能端末でも使えるか? Android 4.4 KitKatの新機能39選
- もはや無料BaaS。ゲーム以外でも使いたくなるGoogle Play Game Servicesのデータ管理機能
- アプリにGoogle+のソーシャルグラフを持ち込めるGoogle Play Game Servicesの基礎知識
- あなたのアプリはクラウドにデータをバックアップできますか?
- Eclipse ADTに代わるIDEとなるか? Android Studioの基礎知識
- ActionBarで、アプリのUIはこんなにスマートになる
- Android 4.x時代のアプリにないと残念なActionBarとは
- 動的クラスローディングでAndroidアプリ“裏”開発
- Android 4.xのAndroidビームをアプリに組み込むには
- AndroidアプリでNFCタグを読み書きするための基礎知識
- 新タブレット時代を見据えるAndroid 4.2の新機能9選
- Androidからイヤフォンやヘルス機器とBluetooth通信するには
- Bluetoothを使ってAndroidアプリ同士で通信するには
- Androidアプリをアプリ内購読に対応してもうける方法
- 開発者が知らないと残念過ぎるAndroid 4.1の新機能36選
- Androidのプロセス間通信を自由自在にするAIDL
- Android 4.0のサービス/プロセス間通信の基本
- Androidアプリでマルチメディアを扱うための基礎知識
- Androidのウィジェットにノーティフィケーションするには
- Android 4.0で注目の顔認識をアプリに組み込むには
- Android 4.0でアプリ開発を始めるための環境構築
- 開発者が知らないと損するAndroid 4.0の新機能44選
- Android Compatibility packageで2.x系でもマルチサイズ対応
- Androidの画面の大きさの違いを解決するFragments
- Android 3.0の新APIで簡単ドラッグ&ドロップ実装
- 開発者が知って得するAndroid 2.3の新機能18選
- アニメーションでAndroidに独創的な画面エフェクトを
- Androidアプリで“アニメーション”するための基礎知識
- XMLレイアウトでAndroidアプリに“設定画面”を追加
- 開発者が知っておきたいAndroid 2.2の新機能12連発
- もはやケータイに必須のカメラをAndroidで制御しよう
- 地図/位置情報/GPSを使うAndroidアプリを作るには
- Android NDKでJNIを使用してアプリを高速化するには
- Android 2.1の新機能「Live Wallpaper」で作る、美しく燃える“待ち受け”
- iPhoneより多彩なAndroidのセンサをアプリで操作
- SurfaceViewならAndroidで高速描画ゲームが作れる
- Android 1.6のジェスチャーとテキスト読み上げを使う
- Androidのホーム画面に常駐するアプリを作るには
- Netbookにも広まるAndroidで、かつてないWeb体験を
- アプリを国際化してAndroid Marketから世界へ発信
- 常駐アプリが作成できるAndroidの“サービス”とは
- AndroidでSQLiteのDB操作をするための基礎知識
- Androidアプリの使いやすさを左右する5つのレイアウト
- 簡単でワクワクするAndroidウィジェット10連発!
- ブラウザや地図、ストリートビューの基、Intentとは?
- Androidアプリ作成の基本“Activity”とは何か?
- Android Market配布を目指しEclipseでHelloWorld!
Copyright © ITmedia, Inc. All Rights Reserved.