1page.title=設定 2page.tags=preference,preferenceactivity,preferencefragment 3 4@jd:body 5 6 7<div id="qv-wrapper"> 8<div id="qv"> 9 10<h2>本書の内容</h2> 11<ol> 12 <li><a href="#Overview">概要</a> 13 <ol> 14 <li><a href="#SettingTypes">プリファレンス</a></li> 15 </ol> 16 </li> 17 <li><a href="#DefiningPrefs">XML にプリファレンスを定義する</a> 18 <ol> 19 <li><a href="#Groups">設定グループを作成する</a></li> 20 <li><a href="#Intents">インテントを使用する</a></li> 21 </ol> 22 </li> 23 <li><a href="#Activity">プリファレンス アクティビティを作成する</a></li> 24 <li><a href="#Fragment">プリファレンス フラグメントを使用する</a></li> 25 <li><a href="#Defaults">デフォルト値を設定する</a></li> 26 <li><a href="#PreferenceHeaders">プリファレンス ヘッダーを使用する</a> 27 <ol> 28 <li><a href="#CreateHeaders">ヘッダー ファイルを作成する</a></li> 29 <li><a href="#DisplayHeaders">ヘッダーを表示する</a></li> 30 <li><a href="#BackCompatHeaders">旧バージョンでプリファレンス ヘッダーをサポートする</a></li> 31 </ol> 32 </li> 33 <li><a href="#ReadingPrefs">プリファレンスを読み込む</a> 34 <ol> 35 <li><a href="#Listening">プリファレンスの変化をリッスンする</a></li> 36 </ol> 37 </li> 38 <li><a href="#NetworkUsage">ネットワークの使用を管理する</a></li> 39 <li><a href="#Custom">カスタム プリファレンスを作成する</a> 40 <ol> 41 <li><a href="#CustomSelected">ユーザー インターフェースを指定する</a></li> 42 <li><a href="#CustomSave">設定の値を保存する</a></li> 43 <li><a href="#CustomInitialize">現在の値を初期化する</a></li> 44 <li><a href="#CustomDefault">デフォルト値を提供する</a></li> 45 <li><a href="#CustomSaveState">プリファレンスの状態を保存し復元する</a></li> 46 </ol> 47 </li> 48</ol> 49 50<h2>キークラス</h2> 51<ol> 52 <li>{@link android.preference.Preference}</li> 53 <li>{@link android.preference.PreferenceActivity}</li> 54 <li>{@link android.preference.PreferenceFragment}</li> 55</ol> 56 57 58<h2>関連ドキュメント</h2> 59<ol> 60 <li><a href="{@docRoot}design/patterns/settings.html">Settings design guide</a></li> 61</ol> 62</div> 63</div> 64 65 66 67 68<p>多くの場合、アプリケーションには、ユーザーがアプリの機能や動作を変更できる設定が含まれています。たとえば、一部のアプリでは、通知を有効にするかどうかや、アプリケーションがクラウドとデータを同期する頻度を、ユーザーが指定できます。 69 70</p> 71 72<p>アプリに設定機能を提供するには、Android の {@link android.preference.Preference} API を使用して、他の Android アプリ(システム設定を含む)の操作と整合性のあるインターフェースを構築する必要があります。 73 74このドキュメントでは、{@link android.preference.Preference} API を使用して、アプリの設定機能を構築する方法について説明します。 75</p> 76 77<div class="note design"> 78<p><strong>設定の設計</strong></p> 79 <p>設定の設計方法については、<a href="{@docRoot}design/patterns/settings.html">設定</a>のデザインガイドをご覧ください。</p> 80</div> 81 82 83<img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" /> 84<p class="img-caption"><strong>図 1.</strong> Android SMS アプリの設定のスクリーンショット 85{@link android.preference.Preference} で定義されたアイテムを選択すると、設定を変更するためのインターフェースが開きます。 86</p> 87 88 89 90 91<h2 id="Overview">概要</h2> 92 93<p>設定は、{@link android.view.View} オブジェクトを使用してユーザー インターフェースを作成する方法ではなく、XML ファイルで宣言された {@link android.preference.Preference} クラスの各種のサブクラスを使用する方法で作成されます。 94 95</p> 96 97<p>1 つの {@link android.preference.Preference} オブジェクトが、1 つの設定の構成要素になります。 98各 {@link android.preference.Preference} はアイテムとしてリストに表示され、ユーザーが設定を変更するための適切な UI を提供します。 99たとえば、{@link android.preference.CheckBoxPreference} はチェックボックスを表示するリストアイテムを作成し、{@link android.preference.ListPreference} は、選択リスト付きのダイアログを開くアイテムを作成します。 100 101</p> 102 103<p>追加した各 {@link android.preference.Preference} は、アプリの設定のためのデフォルトの {@link android.content.SharedPreferences} ファイルに設定を保存するためにシステムが使用する対応するキーと値のペアを持ちます。 104 105ユーザーが設定を変更する場合、システムが {@link android.content.SharedPreferences} ファイルの対応する値を更新します。 106関連する {@link android.content.SharedPreferences} ファイルを直接操作することが必要なのは、ユーザーの設定に基づいてアプリの動作を決定するために値を読み込むことが必要な場合のみです。 107 108</p> 109 110<p>各設定の {@link android.content.SharedPreferences} に保存される値のデータ型は、次のいずれかにすることができます。 111</p> 112 113<ul> 114 <li>Boolean</li> 115 <li>Float</li> 116 <li>Int</li> 117 <li>Long</li> 118 <li>String</li> 119 <li>String {@link java.util.Set}</li> 120</ul> 121 122<p>アプリの設定の UI は {@link android.view.View} オブジェクトではなく {@link android.preference.Preference} で作成されているため、リストの設定を表示するには、専用の {@link android.app.Activity} サブクラスまたは {@link android.app.Fragment} サブクラスを使用する必要があります。 123 124 125</p> 126 127<ul> 128 <li>アプリが 3.0 よりも前のバージョンの Android(API レベル 10 以下)をサポートしている場合は、{@link android.preference.PreferenceActivity} クラスを継承してアクティビティを作成する必要があります。 129</li> 130 <li>Android 3.0 以降では、代わりに、アプリの設定を表示する {@link android.preference.PreferenceFragment} をホストする従来の {@link android.app.Activity} を使用します。ただし、設定のグループが複数ある場合は、{@link android.preference.PreferenceActivity} を使用して大きな画面用の 2 ペイン レイアウトを作成することもできます。 131 132 133</li> 134</ul> 135 136<p>{@link android.preference.PreferenceActivity} と {@link android.preference.PreferenceFragment} のインスタンスの設定方法は、<a href="#Activity">プリファレンス アクティビティを作成する</a>と<a href="#Fragment">プリファレンス フラグメントを使用する</a>セクションをご覧ください。 137 138</p> 139 140 141<h3 id="SettingTypes">プリファレンス</h3> 142 143<p>アプリの各設定は、{@link android.preference.Preference} クラスの個々のサブクラスに相当します。 144各サブクラスには、設定のタイトルやデフォルト値などを指定できる一連の核となるプロパティが含まれています。 145また、各サブクラスは、専用のプロパティとユーザー インターフェースを提供しています。 146たとえば、図 1. は、SMS アプリの設定のスクリーンショットです。 147設定画面の各リスト アイテムは、それぞれ異なる {@link android.preference.Preference} オブジェクトに基づいています。 148</p> 149 150<p>以下は、最も一般的なプリファレンスの一部です。</p> 151 152<dl> 153 <dt>{@link android.preference.CheckBoxPreference}</dt> 154 <dd>有効または無効にする設定のチェックボックス付きのアイテムを表示します。保存される値は、Boolean です(オンの場合、<code>true</code>)。 155</dd> 156 157 <dt>{@link android.preference.ListPreference}</dt> 158 <dd>ラジオボタンのリスト付きのダイアログを開きます。保存される値は、サポートされるデータ型(上記参照)であればどのデータ型にもできます。 159</dd> 160 161 <dt>{@link android.preference.EditTextPreference}</dt> 162 <dd>{@link android.widget.EditText} ウィジェット付きのダイアログを開きます。保存される値は、{@link java.lang.String} です。 163</dd> 164</dl> 165 166<p>その他のサブクラスと対応するプロパティについては、{@link android.preference.Preference} クラスをご覧ください。 167</p> 168 169<p>もちろん、組み込みのクラスがすべてのニーズを満たすわけではなく、アプリケーションがより特殊な機能を必要とする可能性もあります。 170たとえば、プラットフォームは、現時点では、数字や日付を選択するための {@link android.preference.Preference} クラスを提供していません。 171そのため、独自の {@link android.preference.Preference} サブクラスを定義することが必要になる場合もあります。 172詳細については、<a href="#Custom">カスタム プリファレンスを作成する</a>セクションをご覧ください。</p> 173 174 175 176<h2 id="DefiningPrefs">XML にプリファレンスを定義する</h2> 177 178<p>実行時に新しい {@link android.preference.Preference} オブジェクトのインスタンスを作成することもできますが、{@link android.preference.Preference} オブジェクトの階層で XML に設定のリストを定義する必要があります。 179 180XML ファイルは更新が容易な簡単に読むことができる構造を持つため XML ファイルを使用して設定のコレクションを定義することをお勧めします。 181また、アプリの設定は通常、事前設定されていますが、設定のコレクションを実行時に変更することもできます。 182</p> 183 184<p>各 {@link android.preference.Preference} サブクラスは、{@code <CheckBoxPreference>} などのクラス名と一致する XML 要素で定義できます。 185</p> 186 187<p>この XML ファイルは、{@code res/xml/} ディレクトリに保存する必要があります。この XML ファイルには好きな名前を付けることができますが、一般的には、{@code preferences.xml} という名前が使用されています。 188階層の分岐(この分岐がそれ自身の設定のリストを開きます)が {@link android.preference.PreferenceScreen} のネストされたインスタンスを使用して宣言されているため、必要なファイルは通常 1 ファイルのみです。 189 190</p> 191 192<p class="note"><strong>注:</strong> 複数ペイン レイアウトの設定を作成する場合は、フラグメントごとに別々の XML ファイルが必要です。 193</p> 194 195<p>XML ファイルのルートノードは、{@link android.preference.PreferenceScreen <PreferenceScreen>} 要素にする必要があります。 196この要素内に、各 {@link android.preference.Preference} を追加します。 197{@link android.preference.PreferenceScreen <PreferenceScreen>} 要素内に追加したそれぞれの子は、設定のリストで 1 つのアイテムとして表示されます。 198 199</p> 200 201<p>次に例を示します。</p> 202 203<pre> 204<?xml version="1.0" encoding="utf-8"?> 205<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 206 <CheckBoxPreference 207 android:key="pref_sync" 208 android:title="@string/pref_sync" 209 android:summary="@string/pref_sync_summ" 210 android:defaultValue="true" /> 211 <ListPreference 212 android:dependency="pref_sync" 213 android:key="pref_syncConnectionType" 214 android:title="@string/pref_syncConnectionType" 215 android:dialogTitle="@string/pref_syncConnectionType" 216 android:entries="@array/pref_syncConnectionTypes_entries" 217 android:entryValues="@array/pref_syncConnectionTypes_values" 218 android:defaultValue="@string/pref_syncConnectionTypes_default" /> 219</PreferenceScreen> 220</pre> 221 222<p>この例には、{@link android.preference.CheckBoxPreference} と {@link android.preference.ListPreference} が含まれています。 223どちらのアイテムにも次の 3 つの属性が含まれています。</p> 224 225<dl> 226 <dt>{@code android:key}</dt> 227 <dd>この属性は、データ値を保持するプリファレンスで必要です。設定の値を {@link android.content.SharedPreferences} に保存するときにシステムが使用する一意のキー(文字列)を指定します。 228 229 230 <p>プリファレンスが {@link android.preference.PreferenceCategory} または{@link android.preference.PreferenceScreen} の場合、またはプリファレンスが {@link android.content.Intent} の呼び出しを指定している場合(<a href="#Intents">{@code <intent>}</a> 要素を使用)、または {@link android.app.Fragment} の表示を指定している場合(<a href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code android:fragment}</a> 属性を使用)のみ、インスタンスでこの属性は<em>必要ありません</em>。 231 232 233</p> 234 </dd> 235 <dt>{@code android:title}</dt> 236 <dd>この属性は、ユーザーに表示される設定の名前です。</dd> 237 <dt>{@code android:defaultValue}</dt> 238 <dd>この属性は、システムが {@link android.content.SharedPreferences} ファイルに設定する必要がある初期値を指定します。 239すべての設定のデフォルト値を指定する必要があります。 240</dd> 241</dl> 242 243<p>その他のサポートされている属性については、{@link android.preference.Preference}(と対応するサブクラス)のドキュメントをご覧ください。 244</p> 245 246 247<div class="figure" style="width:300px"> 248 <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" /> 249 <p class="img-caption"><strong>図 2.</strong> カテゴリを設定しタイトルを付ける 250 <br/><b>1.</b>カテゴリは、{@link android.preference.PreferenceCategory <PreferenceCategory>} 要素で指定します。 251 <br/><b>2.</b>タイトルは、{@code android:title} 属性で指定します。 252</p> 253</div> 254 255 256<p>設定のリストが 10 アイテムを超える場合は、タイトルを追加して設定のグループを定義するか、それらのグループを別の画面に表示することをお勧めします。 257 258詳細については、次のセクションで説明します。</p> 259 260 261<h3 id="Groups">設定グループを作成する</h3> 262 263<p>10 以上の設定のリストがある場合、ユーザーが目を通して把握し処理することが難しくなる場合があります。 264この問題を解決するには、設定の一部またはすべてをグループに分割し、1 つの長いリストを複数の短いリストに変えます。 265 266関連設定のグループは、次の 2 つの方法のいずれかで表示できます。</p> 267 268<ul> 269 <li><a href="#Titles">タイトルを使用する</a></li> 270 <li><a href="#Subscreens">サブ画面を使用する</a></li> 271</ul> 272 273<p>これらのグループ化方法の 1 つまたは両方を利用して、アプリの設定を整理できます。使用する方法と設定の分割方法を決定する際は、Android Design の<a href="{@docRoot}design/patterns/settings.html">Settings</a> ガイドのガイドラインに従ってください。 274 275</p> 276 277 278<h4 id="Titles">タイトルを使用する</h4> 279 280<p>設定のグループの間に見出しを入れる場合(図 2. 参照)、{@link android.preference.Preference} オブジェクトをグループごとに 1 つの {@link android.preference.PreferenceCategory} 内にセットしてください。 281 282</p> 283 284<p>次に例を示します。</p> 285 286<pre> 287<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 288 <PreferenceCategory 289 android:title="@string/pref_sms_storage_title" 290 android:key="pref_key_storage_settings"> 291 <CheckBoxPreference 292 android:key="pref_key_auto_delete" 293 android:summary="@string/pref_summary_auto_delete" 294 android:title="@string/pref_title_auto_delete" 295 android:defaultValue="false"... /> 296 <Preference 297 android:key="pref_key_sms_delete_limit" 298 android:dependency="pref_key_auto_delete" 299 android:summary="@string/pref_summary_delete_limit" 300 android:title="@string/pref_title_sms_delete"... /> 301 <Preference 302 android:key="pref_key_mms_delete_limit" 303 android:dependency="pref_key_auto_delete" 304 android:summary="@string/pref_summary_delete_limit" 305 android:title="@string/pref_title_mms_delete" ... /> 306 </PreferenceCategory> 307 ... 308</PreferenceScreen> 309</pre> 310 311 312<h4 id="Subscreens">サブ画面を使用する</h4> 313 314<p>設定のグループをサブ画面に配置する場合(図 3. 参照)、{@link android.preference.Preference} オブジェクトのグループを {@link android.preference.PreferenceScreen} 内にセットしてください。 315 316</p> 317 318<img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" /> 319<p class="img-caption"><strong>図 3.</strong> 子画面を設定する。{@code <PreferenceScreen>} は、選択されると、ネストされた設定を表示するための個別のリストを開くアイテムを作成します。 320 321</p> 322 323<p>次に例を示します。</p> 324 325<pre> 326<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 327 <!-- opens a subscreen of settings --> 328 <PreferenceScreen 329 android:key="button_voicemail_category_key" 330 android:title="@string/voicemail" 331 android:persistent="false"> 332 <ListPreference 333 android:key="button_voicemail_provider_key" 334 android:title="@string/voicemail_provider" ... /> 335 <!-- opens another nested subscreen --> 336 <PreferenceScreen 337 android:key="button_voicemail_setting_key" 338 android:title="@string/voicemail_settings" 339 android:persistent="false"> 340 ... 341 </PreferenceScreen> 342 <RingtonePreference 343 android:key="button_voicemail_ringtone_key" 344 android:title="@string/voicemail_ringtone_title" 345 android:ringtoneType="notification" ... /> 346 ... 347 </PreferenceScreen> 348 ... 349</PreferenceScreen> 350</pre> 351 352 353<h3 id="Intents">インテントを使用する</h3> 354 355<p>設定画面ではなく、ウェブページを表示するためのウェブブラウザなどの別のアクティビティを開くプリファレンス アイテムが必要になることもあります。 356ユーザーがプリファレンス アイテムを選択したときに {@link android.content.Intent} が呼び出されるようにするには、対応する {@code <Preference>} 要素の子として {@code <intent>} 要素を追加します。 357 358</p> 359 360<p>たとえば、次の方法で、プリファレンス アイテムを使用してウェブページを開くことができます。</p> 361 362<pre> 363<Preference android:title="@string/prefs_web_page" > 364 <intent android:action="android.intent.action.VIEW" 365 android:data="http://www.example.com" /> 366</Preference> 367</pre> 368 369<p>次の属性を使用して、明示的なインテントと黙示的なインテントの両方を作成できます。</p> 370 371<dl> 372 <dt>{@code android:action}</dt> 373 <dd>{@link android.content.Intent#setAction setAction()} メソッドで割り当てるアクション。 374</dd> 375 <dt>{@code android:data}</dt> 376 <dd>{@link android.content.Intent#setData setData()} メソッドで割り当てるデータ。</dd> 377 <dt>{@code android:mimeType}</dt> 378 <dd>{@link android.content.Intent#setType setType()} メソッドで割り当てる MIME タイプ。 379</dd> 380 <dt>{@code android:targetClass}</dt> 381 <dd>{@link android.content.Intent#setComponent setComponent()} メソッドでのコンポーネント名のクラス部分。 382</dd> 383 <dt>{@code android:targetPackage}</dt> 384 <dd>{@link android.content.Intent#setComponent setComponent()} メソッドでのコンポーネント名のパッケージ部分。 385</dd> 386</dl> 387 388 389 390<h2 id="Activity">プリファレンス アクティビティを作成する</h2> 391 392<p>アクティビティに設定を表示するには、{@link android.preference.PreferenceActivity} クラスを継承します。 393このクラスは、{@link android.preference.Preference} オブジェクトの階層に基づいて設定のリストを表示する従来の {@link android.app.Activity} クラスを継承したものです。 394 395{@link android.preference.PreferenceActivity} は、ユーザーが変更を行ったときに、各 {@link android.preference.Preference} に対応する設定を自動的に保存します。 396 397</p> 398 399<p class="note"><strong>注:</strong> Android 3.0 以降向けにアプリケーションを開発する場合は、代わりに {@link android.preference.PreferenceFragment} を使用する必要があります。 400<a href="#Fragment">プリファレンス フラグメントの使用</a>についての詳細は、次のセグメントをご覧ください。 401</p> 402 403<p>注意する必要があるのは、{@link android.preference.PreferenceActivity#onCreate onCreate()} のコールバック時に、ビューのレイアウトをロードしてはならないことを忘れないでください。 404代わりに {@link android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} を呼び出し、XML ファイルで宣言済みのプリファレンスをアクティビティに追加する必要があります。 405 406以下は、{@link android.preference.PreferenceActivity} を機能させるために最小限必要なコードです。 407</p> 408 409<pre> 410public class SettingsActivity extends PreferenceActivity { 411 @Override 412 public void onCreate(Bundle savedInstanceState) { 413 super.onCreate(savedInstanceState); 414 addPreferencesFromResource(R.xml.preferences); 415 } 416} 417</pre> 418 419<p>ユーザーがプリファレンスを変更するとすぐに、ユーザーの設定のチェックが必要なときに他のアプリケーション コンポーネントが読み取ることができるデフォルトの {@link android.content.SharedPreferences} ファイルにシステムによって変更が保存されるため、実際一部のアプリではこのコードで十分です。 420 421ただし、多くのアプリでは、プリファレンスに発生する変化をリッスンするために、もう少し多くのコードが必要になります。{@link android.content.SharedPreferences} ファイルの変更のリッスンについての詳細は、<a href="#ReadingPrefs">プリファレンスの読み取り</a>についてのセクションをご覧ください。 422 423 424</p> 425 426 427 428 429<h2 id="Fragment">プリファレンス フラグメントを使用する</h2> 430 431<p>Android 3.0(API レベル 11)以降向けに開発を行っている場合は、{@link android.preference.PreferenceFragment} を使用して {@link android.preference.Preference} オブジェクトのリストを表示する必要があります。 432 433{@link android.preference.PreferenceFragment} はどのアクティビティにでも追加できます — {@link android.preference.PreferenceActivity} を使用する必要はありません。 434</p> 435 436<p>作成するアクティビティの種類にかかわらず、<a href="{@docRoot}guide/components/fragments.html">フラグメント</a>を使用すると、アクティビティを単体で使用する場合と比べて、柔軟なアーキテクチャを持つアプリケーションを作成できます。 437 438そのため、可能な限り {@link android.preference.PreferenceActivity} ではなく、{@link android.preference.PreferenceFragment} を使用して設定の表示を管理することをお勧めします。 439 440</p> 441 442<p>{@link android.preference.PreferenceFragment} の実装は、{@link android.preference.PreferenceFragment#onCreate onCreate()} メソッドを {@link android.preference.PreferenceFragment#addPreferencesFromResource addPreferencesFromResource()} を使用してプリファレンス ファイルをロードするように定義するだけと簡単です。 443 444 445次に例を示します。</p> 446 447<pre> 448public static class SettingsFragment extends PreferenceFragment { 449 @Override 450 public void onCreate(Bundle savedInstanceState) { 451 super.onCreate(savedInstanceState); 452 453 // Load the preferences from an XML resource 454 addPreferencesFromResource(R.xml.preferences); 455 } 456 ... 457} 458</pre> 459 460<p>他の {@link android.app.Fragment} と同様に、このフラグメントは {@link android.app.Activity} に追加できます。 461次に例を示します。</p> 462 463<pre> 464public class SettingsActivity extends Activity { 465 @Override 466 protected void onCreate(Bundle savedInstanceState) { 467 super.onCreate(savedInstanceState); 468 469 // Display the fragment as the main content. 470 getFragmentManager().beginTransaction() 471 .replace(android.R.id.content, new SettingsFragment()) 472 .commit(); 473 } 474} 475</pre> 476 477<p class="note"><strong>注:</strong> {@link android.preference.PreferenceFragment} は、独自の {@link android.content.Context} オブジェクトを持ちません。 478{@link android.content.Context} オブジェクトが必要な場合は、{@link android.app.Fragment#getActivity()} を呼び出すことができます。 479ただし、{@link android.app.Fragment#getActivity()} はフラグメントがアクティビティにアタッチされている場合にのみ呼び出すようにしてください。 480フラグメントがまだアタッチされていない場合や、ライフサイクルの終了時にデタッチされた場合は、{@link android.app.Fragment#getActivity()} は null を返します。 481 482</p> 483 484 485<h2 id="Defaults">デフォルト値を設定する</h2> 486 487<p>作成するプリファレンスは、多くの場合、アプリケーションにとって重要ないくつかの動作を定義します。そのため、ユーザーが最初にプリケーションを開いたときに、各 {@link android.preference.Preference} のデフォルト値で、関連する {@link android.content.SharedPreferences} ファイルを初期化する必要があります。 488 489 490</p> 491 492<p>まず、{@code android:defaultValue} 属性を使用して、XML ファイルの各 {@link android.preference.Preference} オブジェクトにデフォルト値を指定してください。 493 494指定する値は、対応する {@link android.preference.Preference} オブジェクトで使用できるデータ型であればどのようなデータ型でもかまいません。 495次に例を示します。 496</p> 497 498<pre> 499<!-- default value is a boolean --> 500<CheckBoxPreference 501 android:defaultValue="true" 502 ... /> 503 504<!-- default value is a string --> 505<ListPreference 506 android:defaultValue="@string/pref_syncConnectionTypes_default" 507 ... /> 508</pre> 509 510<p>次に、アプリケーションのメイン アクティビティ、およびユーザーがアプリケーションを最初に開いたときに表示されるその他のアクティビティの {@link android.app.Activity#onCreate onCreate()} メソッドから、{@link android.preference.PreferenceManager#setDefaultValues setDefaultValues()} を呼び出します。 511 512 513</p> 514 515<pre> 516PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false); 517</pre> 518 519<p>{@link android.app.Activity#onCreate onCreate()} 時に、このメソッドを呼び出すと、アプリケーションがデフォルト設定で適切に初期化されます。アプリケーションには、動作(セルラー ネットワーク上でデータをダウンロードするかどうかなど)を決定するために、デフォルト設定を読み込むことが必要な場合があります。 520 521 522</p> 523 524<p>このメソッドは次の 3 つの引数を取ります。</p> 525<ul> 526 <li>アプリケーションの {@link android.content.Context}。</li> 527 <li>デフォルト値を設定するプリファレンス XML ファイルのリソース ID。</li> 528 <li>デフォルト値を複数回設定すべきかどうかを示すブール値。 529<p><code>false</code> の場合、デフォルト値は過去にこのメソッドが 1 度も呼ばれたことがない場合(または、デフォルト値の共有プリファレンス ファイルの{@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES} が false の場合)のみ設定されます。 530 531</p></li> 532</ul> 533 534<p>この 3 番目の引数を <code>false</code> に設定している限り、アクティビティが開始するたびに、ユーザーが保存したプリファレンスをデフォルト値にリセットして上書きすることなく、安全にこのメソッドを呼び出すことができます。 535 536この引数を <code>true</code> に設定した場合は、以前の値がすべてデフォルト値で上書きされます。 537</p> 538 539 540 541<h2 id="PreferenceHeaders">プリファレンス ヘッダーを使用する</h2> 542 543<p>まれに、最初の画面が<a href="#Subscreens">サブ画面</a>のリストのみを表示するように設定を設計した方がよい場合もあります(図 4. と図. 5 のシステム設定アプリなど)。 544 545このような設計を Android 3.0 以降で開発する場合、ネストした {@link android.preference.PreferenceScreen} 要素でサブ画面を作成するのではなく、Android 3.0 の新しい「ヘッダー」機能を使用する必要があります。 546 547</p> 548 549<p>ヘッダーを使用して設定を作成するには、次の準備が必要です。</p> 550<ol> 551 <li>設定をグループごとに {@link android.preference.PreferenceFragment} の別々のインスタンスに分けます。 552この場合、設定のグループごとに、個別の XML ファイルが必要になります。 553</li> 554 <li>各設定グループをリストアップし対応する設定のリストを含むのがどのフラグメントかを宣言する XML ヘッダー ファイルを作成します。 555</li> 556 <li>{@link android.preference.PreferenceActivity} クラスを継承し、設定をホストします。</li> 557 <li>{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} コールバックを実装して、ヘッダー ファイルを指定します。 558 559</li> 560</ol> 561 562<p>この設計を使用する大きなメリットは、大きな画面で実行する場合に、{@link android.preference.PreferenceActivity} によって自動的に図. 4 の 2 ペイン レイアウトで表示されることです。 563</p> 564 565<p>アプリケーションが 3.0 より前のバージョンの Android をサポートしている場合でも、3.0 より前の端末で従来の多画面階層をサポートしながら、{@link android.preference.PreferenceFragment} を使用して 3.0 以降の端末で 2 ペイン表示を行うことができます(詳細については、<a href="#BackCompatHeaders">旧バージョンでのプリファレンス ヘッダーのサポート</a>についてのセクションをご覧ください)。 566 567 568 569</p> 570 571<img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" /> 572<p class="img-caption"><strong>図 4.</strong>ヘッダー付きの 2 ペイン レイアウト。 <br/><b>1.</b>ヘッダーは、XML ヘッダー ファイルで定義します。 573 <br/><b>2.</b>設定の各グループは、XML ヘッダー ファイルの {@code <header>} 要素で指定された {@link android.preference.PreferenceFragment} ファイルで定義します。 574 575</p> 576 577<img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" /> 578<p class="img-caption"><strong>図 5.</strong> ヘッダーが設定されたモバイル端末。アイテムが選択されると、対応する {@link android.preference.PreferenceFragment} がヘッダーを置き換えます。 579 580</p> 581 582 583<h3 id="CreateHeaders" style="clear:left">ヘッダー ファイルを作成する</h3> 584 585<p>ヘッダーのリストの設定の各グループは、ルート {@code <preference-headers>} 要素内の単独の {@code <header>} 要素によって指定されます。 586次に例を示します。</p> 587 588<pre> 589<?xml version="1.0" encoding="utf-8"?> 590<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> 591 <header 592 android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne" 593 android:title="@string/prefs_category_one" 594 android:summary="@string/prefs_summ_category_one" /> 595 <header 596 android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo" 597 android:title="@string/prefs_category_two" 598 android:summary="@string/prefs_summ_category_two" > 599 <!-- key/value pairs can be included as arguments for the fragment. --> 600 <extra android:name="someKey" android:value="someHeaderValue" /> 601 </header> 602</preference-headers> 603</pre> 604 605<p>{@code android:fragment} 属性を使用して、各ヘッダーは、ユーザーがヘッダーを選択したときに開く {@link android.preference.PreferenceFragment} のインスタンスを宣言します。 606</p> 607 608<p>{@code <extras>} 要素を使用すると、キーと値のペアを {@link android.os.Bundle} のフラグメントに渡すことができます。 609{@link android.app.Fragment#getArguments()} を呼び出すことで、フラグメントは引数を取得できます。 610さまざまな理由でフラグメントに引数を渡す場合がありますが、各グループの {@link android.preference.PreferenceFragment} の同じサブクラスを再利用し、引数を使用してフラグメントがロードするプリファレンス XML ファイルを指定することは、効果的な引数の使い方の 1 つです。 611 612 613</p> 614 615<p>たとえば、次のフラグメントは、各ヘッダーが {@code "settings"} キーを使用して {@code <extra>} 引数を定義している場合、複数の設定グループで再利用できます。 616</p> 617 618<pre> 619public static class SettingsFragment extends PreferenceFragment { 620 @Override 621 public void onCreate(Bundle savedInstanceState) { 622 super.onCreate(savedInstanceState); 623 624 String settings = getArguments().getString("settings"); 625 if ("notifications".equals(settings)) { 626 addPreferencesFromResource(R.xml.settings_wifi); 627 } else if ("sync".equals(settings)) { 628 addPreferencesFromResource(R.xml.settings_sync); 629 } 630 } 631} 632</pre> 633 634 635 636<h3 id="DisplayHeaders">ヘッダーを表示する</h3> 637 638<p>プリファレンス ヘッダーを表示するには、{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} コールバックメソッドを実装し、{@link android.preference.PreferenceActivity#loadHeadersFromResource loadHeadersFromResource()} を呼び出す必要があります。 639 640 641次に例を示します。</p> 642 643<pre> 644public class SettingsActivity extends PreferenceActivity { 645 @Override 646 public void onBuildHeaders(List<Header> target) { 647 loadHeadersFromResource(R.xml.preference_headers, target); 648 } 649} 650</pre> 651 652<p>ユーザーがヘッダーのリストからアイテムを選択した場合、システムが対応する {@link android.preference.PreferenceFragment} を開きます。 653</p> 654 655<p class="note"><strong>注:</strong> プリファレンス ヘッダーを使用する場合、アクティビティで必要なタスクはヘッダーのロードのみであるため、{@link android.preference.PreferenceActivity} のサブクラスが {@link android.preference.PreferenceActivity#onCreate onCreate()} メソッドを実装する必要はありません。 656 657 658</p> 659 660 661<h3 id="BackCompatHeaders">旧バージョンでプリファレンス ヘッダーをサポートする</h3> 662 663<p>アプリケーションが Android 3.0 よりも前のバージョンをサポートしている場合でも、3.0 以降で実行するときに、ヘッダーを使用して 2 ペイン レイアウトを提供できます。 664必要なことは、3.0 よりも前のバージョンの Android で使用するために、ヘッダー アイテムのように動作する基本的な {@link android.preference.Preference <Preference>} 要素を使用する追加のプリファレンス XML ファイルを作成することだけです。 665 666 667</p> 668 669<p>新しい {@link android.preference.PreferenceScreen} を開く代わりに、各 {@link android.preference.Preference <Preference>} 要素が、ロードするプリファレンス XML ファイルが指定されている {@link android.preference.PreferenceActivity} に {@link android.content.Intent} を送ります。 670 671 672</p> 673 674<p>たとえば、以下は Android 3.0 以降で使用されるプリファレンス ヘッダーの XML ファイル({@code res/xml/preference_headers.xml})です。 675</p> 676 677<pre> 678<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> 679 <header 680 android:fragment="com.example.prefs.SettingsFragmentOne" 681 android:title="@string/prefs_category_one" 682 android:summary="@string/prefs_summ_category_one" /> 683 <header 684 android:fragment="com.example.prefs.SettingsFragmentTwo" 685 android:title="@string/prefs_category_two" 686 android:summary="@string/prefs_summ_category_two" /> 687</preference-headers> 688</pre> 689 690<p>また、以下は Android 3.0 よりも前のバージョンに同じヘッダーを提供するプリファレンス ファイル({@code res/xml/preference_headers_legacy.xml})です。 691</p> 692 693<pre> 694<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 695 <Preference 696 android:title="@string/prefs_category_one" 697 android:summary="@string/prefs_summ_category_one" > 698 <intent 699 android:targetPackage="com.example.prefs" 700 android:targetClass="com.example.prefs.SettingsActivity" 701 android:action="com.example.prefs.PREFS_ONE" /> 702 </Preference> 703 <Preference 704 android:title="@string/prefs_category_two" 705 android:summary="@string/prefs_summ_category_two" > 706 <intent 707 android:targetPackage="com.example.prefs" 708 android:targetClass="com.example.prefs.SettingsActivity" 709 android:action="com.example.prefs.PREFS_TWO" /> 710 </Preference> 711</PreferenceScreen> 712</pre> 713 714<p>{@code <preference-headers>} のサポートは Android 3.0 で追加されたため、Android 3.0 以降で実行されている場合のみ、システムは {@link android.preference.PreferenceActivity} の {@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} を呼び出します。 715 716「レガシー」ヘッダー ファイル({@code preference_headers_legacy.xml})をロードするには、Android のバージョンを確認し、Android 3.0({@link android.os.Build.VERSION_CODES#HONEYCOMB})よりも前のバージョンの場合、{@link android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} を呼び出す必要があります。 717 718 719 720 721次に例を示します。</p> 722 723<pre> 724@Override 725public void onCreate(Bundle savedInstanceState) { 726 super.onCreate(savedInstanceState); 727 ... 728 729 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 730 // Load the legacy preferences headers 731 addPreferencesFromResource(R.xml.preference_headers_legacy); 732 } 733} 734 735// Called only on Honeycomb and later 736@Override 737public void onBuildHeaders(List<Header> target) { 738 loadHeadersFromResource(R.xml.preference_headers, target); 739} 740</pre> 741 742<p>残りの手順は、アクティビティに渡される {@link android.content.Intent} を処理して、ロードするプリファレンス ファイルを指定するだけです。 743それには、インテントのアクションを取得し、プリファレンス XML の {@code <intent>} タグで使用した既知のアクション文字列と比較します。 744</p> 745 746<pre> 747final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE"; 748... 749 750@Override 751public void onCreate(Bundle savedInstanceState) { 752 super.onCreate(savedInstanceState); 753 754 String action = getIntent().getAction(); 755 if (action != null && action.equals(ACTION_PREFS_ONE)) { 756 addPreferencesFromResource(R.xml.preferences); 757 } 758 ... 759 760 else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 761 // Load the legacy preferences headers 762 addPreferencesFromResource(R.xml.preference_headers_legacy); 763 } 764} 765</pre> 766 767<p>{@link android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} の連続呼び出しは、すべてのプリファレンスを 1 つのリストにスタックすることに注意してください。そのため、else if ステートメントを使用して条件を適切に記述して、1 度のみ呼び出されるようにしてください。 768 769 770</p> 771 772 773 774 775 776<h2 id="ReadingPrefs">プリファレンスを読み込む</h2> 777 778<p>デフォルトでは、アプリのプリファレンスは、静的メソッド {@link android.preference.PreferenceManager#getDefaultSharedPreferences PreferenceManager.getDefaultSharedPreferences()} を呼び出すとアプリケーション内のどこからでもアクセス可能なファイルに保存されます。 779 780 781このメソッドは、{@link android.preference.PreferenceActivity} で使用される {@link android.preference.Preference} オブジェクトに関連するすべてのキーと値のペアを含む {@link android.content.SharedPreferences} を返します。 782 783 784</p> 785 786<p>たとえば、次の方法で、アプリケーションのその他のアクティビティからプリファレンスの値の 1 つを読み込むことができます。 787</p> 788 789<pre> 790SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 791String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, ""); 792</pre> 793 794 795 796<h3 id="Listening">プリファレンスの変化をリッスンする</h3> 797 798<p>さまざまな理由で、ユーザーがプリファレンスを変更してすぐに通知を受け取ることが必要になることがあります。 799プリファレンスの 1 つに変化が発生したときにコールバックを受け取るには、 {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener SharedPreference.OnSharedPreferenceChangeListener} インターフェースを実装し、{@link android.content.SharedPreferences#registerOnSharedPreferenceChangeListener registerOnSharedPreferenceChangeListener()} を呼び出して {@link android.content.SharedPreferences} オブジェクトにリスナを登録します。 800 801 802 803 804</p> 805 806<p>このインターフェースには、コールバック メソッドが {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged onSharedPreferenceChanged()} 1 つのみしか含まれておらず、アクティビティの一部として簡単に実装できます。 807 808 809次に例を示します。</p> 810 811<pre> 812public class SettingsActivity extends PreferenceActivity 813 implements OnSharedPreferenceChangeListener { 814 public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType"; 815 ... 816 817 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 818 String key) { 819 if (key.equals(KEY_PREF_SYNC_CONN)) { 820 Preference connectionPref = findPreference(key); 821 // Set summary to be the user-description for the selected value 822 connectionPref.setSummary(sharedPreferences.getString(key, "")); 823 } 824 } 825} 826</pre> 827 828<p>この例では、メソッドが、変更された設定が、既知のプリファレンス キーの設定かどうかチェックしています。メソッドは {@link android.preference.PreferenceActivity#findPreference findPreference()} を呼び出して、変更された {@link android.preference.Preference} オブジェクトを取得しています。これにより、メソッドは、ユーザー選択の説明として表示されるアイテムの概要を変更できます。 829 830 831つまり、その設定が {@link android.preference.ListPreference} またはその他の複数選択可の設定の場合、設定が変更されたときに {@link android.preference.Preference#setSummary setSummary()} を呼び出して現在のステータス(図 5. のスリープ設定など)を表示する必要があります。 832 833 834</p> 835 836<p class="note"><strong>注:</strong> Android Design の <a href="{@docRoot}design/patterns/settings.html">Settings</a> に説明されているように、ユーザーがプリファレンスを変更するごとに、{@link android.preference.ListPreference} の概要を更新して最新の設定を表示することをお勧めします。 837 838</p> 839 840<p>アクティビティでの適切なライフサイクル管理のために、{@link android.app.Activity#onResume} と {@link android.app.Activity#onPause} のそれぞれのコールバック時に、{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} の登録と登録解除を行うことをお勧めします。 841 842</p> 843 844<pre> 845@Override 846protected void onResume() { 847 super.onResume(); 848 getPreferenceScreen().getSharedPreferences() 849 .registerOnSharedPreferenceChangeListener(this); 850} 851 852@Override 853protected void onPause() { 854 super.onPause(); 855 getPreferenceScreen().getSharedPreferences() 856 .unregisterOnSharedPreferenceChangeListener(this); 857} 858</pre> 859 860<p class="caution"><strong>警告:</strong> {@link android.content.SharedPreferences#registerOnSharedPreferenceChangeListener registerOnSharedPreferenceChangeListener()} を呼び出す場合、現時点では、プリファレンス マネージャーにはリスナへの強い参照を格納できません。 861 862 863リスナへの強い参照を格納しない場合は、リスナがガベージ コレクションの影響を受けやすくなります。 864リスナが必要な間存在し続けるオブジェクトのインスタンス データ内に、リスナへの参照を保持することをお勧めします。 865 866</p> 867 868<p>たとえば、以下のコードでは、呼び出し元は、リスナへの参照を保持していません。 869結果として、リスナはガベージ コレクションの影響を受けることになり、その後のいずれかの時点でエラーになります。 870</p> 871 872<pre> 873prefs.registerOnSharedPreferenceChangeListener( 874 // Bad! The listener is subject to garbage collection! 875 new SharedPreferences.OnSharedPreferenceChangeListener() { 876 public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 877 // listener implementation 878 } 879}); 880</pre> 881 882<p>そのため、リスナが必要な間存在し続けるオブジェクトのインスタンス データ フィールドに、リスナへの参照を格納してください。 883</p> 884 885<pre> 886SharedPreferences.OnSharedPreferenceChangeListener listener = 887 new SharedPreferences.OnSharedPreferenceChangeListener() { 888 public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 889 // listener implementation 890 } 891}; 892prefs.registerOnSharedPreferenceChangeListener(listener); 893</pre> 894 895<h2 id="NetworkUsage">ネットワークの使用を管理する</h2> 896 897 898<p>Android 4.0 以降では、フォアグラウンドとバックグラウンドでのアプリケーションのネットワーク データの使用量を、システムの設定アプリケーションでユーザーが確認できます。 899また、ユーザーは、個々のアプリのバックグラウンド データの使用を無効にできます。 900アプリのバックグラウンドからのデータへのアクセスをユーザーが無効にすることを防ぐには、データ接続を効率的に使用することと、アプリケーションの設定でアプリのデータの利用方法をユーザーが調整できるようにすることが必要です。 901 902<p> 903 904<p>たとえば、データを同期する頻度や、Wi-Fi 上でのみアップロードやダウンロードを実行するようにするかどうか、ローミング時にデータを使用するかどうかなどを、ユーザーが設定できるようにすることができます。 905これらをユーザーが管理できる場合、システム設定に設定した限度にデータ使用量が近づいたときに、データへのアプリのアクセスをユーザーが無効にする可能性は減少します。ユーザーはアプリのアクセスを無効にする代わりに、アプリのデータの使用量を厳密に管理できます。 906 907 908</p> 909 910<p>アプリのデータ使用を管理するために {@link android.preference.PreferenceActivity} に必要なプリファレンスを追加したら、マニフェスト ファイルに {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} のインテント フィルタを追加する必要があります。 911 912次に例を示します。</p> 913 914<pre> 915<activity android:name="SettingsActivity" ... > 916 <intent-filter> 917 <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" /> 918 <category android:name="android.intent.category.DEFAULT" /> 919 </intent-filter> 920</activity> 921</pre> 922 923<p>このインテント フィルタは、これがアプリケーションのデータ使用をコントロールしているアクティビティであるとシステムに示します。 924これにより、ユーザーがシステム設定アプリからアプリのデータ使用量を調べるときに、[<em>View application settings</em>] ボタンを使用できるようになります。このボタンを押すと、{@link android.preference.PreferenceActivity} が開始し、アプリのデータ使用量を調整できるようになります。 925 926 927</p> 928 929 930 931 932 933 934 935<h2 id="Custom">カスタム プリファレンスを作成する</h2> 936 937<p>Android フレームワークには、異なる設定タイプの UI を作成できるさまざまな {@link android.preference.Preference} サブクラスが含まれています。ただし、番号ピッカーや日付ピッカーなど、組み込みソリューションがない場合に必要な設定が存在する可能性もあります。 938 939 940このような場合、{@link android.preference.Preference} クラスまたは他のサブクラスの 1 つを継承して、カスタム プリファレンスを作成する必要があります。 941</p> 942 943<p>{@link android.preference.Preference} クラスを継承する場合、次のことが必要です。 944</p> 945 946<ul> 947 <li>ユーザーがその設定を選択したときに表示されるユーザー インターフェースを指定する。</li> 948 <li>適切なタイミングで設定の値を保存する。</li> 949 <li>{@link android.preference.Preference} が表示されるときに、現在の値(またはデフォルト値)で初期化する。 950</li> 951 <li>システムによってリクエストされた場合にデフォルト値を提供する。</li> 952 <li>{@link android.preference.Preference} が独自の UI(ダイアログなど)を提供している場合、状態を保存し復元してライフサイクルの変化を処理する(ユーザーが画面を回転させた場合など)。 953</li> 954</ul> 955 956<p>以下の各セクションでは、上記の各事項を実現する方法を説明します。</p> 957 958 959 960<h3 id="CustomSelected">ユーザー インターフェースを指定する</h3> 961 962 <p>{@link android.preference.Preference} クラスを直接継承する場合、{@link android.preference.Preference#onClick()} を実装して、ユーザーがアイテムを選択したときに発生するアクションを定義する必要があります。 963 964ただし、大部分のカスタム設定では、手順が簡単な {@link android.preference.DialogPreference} を継承してダイアログを表示する方法が利用されています。 965{@link android.preference.DialogPreference} を継承する場合、クラス コンストラクタで {@link android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()} を呼び出してダイアログのレイアウトを指定する必要があります。 966 967 968</p> 969 970 <p>たとえば、以下のカスタム {@link android.preference.DialogPreference} のコンストラクタでは、レイアウトを宣言しデフォルトのポジティブとネガティブのダイアログ ボタンのテキストを指定しています。 971 972</p> 973 974<pre> 975public class NumberPickerPreference extends DialogPreference { 976 public NumberPickerPreference(Context context, AttributeSet attrs) { 977 super(context, attrs); 978 979 setDialogLayoutResource(R.layout.numberpicker_dialog); 980 setPositiveButtonText(android.R.string.ok); 981 setNegativeButtonText(android.R.string.cancel); 982 983 setDialogIcon(null); 984 } 985 ... 986} 987</pre> 988 989 990 991<h3 id="CustomSave">設定の値を保存する</h3> 992 993<p>設定の値が整数の場合、またはブール値を保存する{@link android.preference.Preference#persistBoolean persistBoolean()} の場合、{@link android.preference.Preference#persistInt persistInt()} など、{@link android.preference.Preference} クラスの {@code persist*()} メソッドのいずれかを呼び出すことで、設定の値をいつでも保存できます。 994 995 996</p> 997 998<p class="note"><strong>注:</strong> 各 {@link android.preference.Preference} には、1 つのデータ型のデータのみ保存できます。そのため、カスタム {@link android.preference.Preference} で使用されているデータ型に対応する {@code persist*()} メソッドを使用する必要があります。 999 1000</p> 1001 1002<p>設定をいつ保存したらよいかは、継承する {@link android.preference.Preference} クラスによって異なります。 1003{@link android.preference.DialogPreference} を継承する場合、ポジティブな結果でダイアログが閉じられたとき(ユーザーが [OK] ボタンを選択したとき)のみ、値を保存する必要があります。 1004 1005</p> 1006 1007<p>{@link android.preference.DialogPreference} が閉じられたときには、システムが {@link android.preference.DialogPreference#onDialogClosed onDialogClosed()} メソッドを呼び出します。 1008このメソッドには、ユーザーの結果が「Positive」かどうかを指定するブール値の引数が含まれています — この値が <code>true</code> の場合はユーザーがポジティブ ボタンを選択しているということであり、新しい値を保存する必要があります。 1009 1010次に例を示します。 1011</p> 1012 1013<pre> 1014@Override 1015protected void onDialogClosed(boolean positiveResult) { 1016 // When the user selects "OK", persist the new value 1017 if (positiveResult) { 1018 persistInt(mNewValue); 1019 } 1020} 1021</pre> 1022 1023<p>この例では、<code>mNewValue</code> は、設定の現在の値を保持するクラスの 1 つです。 1024{@link android.preference.Preference#persistInt persistInt()} を呼び出すと、値が {@link android.content.SharedPreferences} ファイルに保存されます(この {@link android.preference.Preference} の XML ファイルに指定されたキーを自動的に使用して保存されます)。 1025 1026</p> 1027 1028 1029<h3 id="CustomInitialize">現在の値を初期化する</h3> 1030 1031<p>システムは {@link android.preference.Preference} を画面に追加すると、{@link android.preference.Preference#onSetInitialValue onSetInitialValue()} を呼び出し、その設定用に保存されている値がある場合は通知します。 1032 1033保存されている値がない場合、この呼び出しによりデフォルト値が設定されます。 1034</p> 1035 1036<p>この {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} メソッドは、ブール値の <code>restorePersistedValue</code> を、その設定用に値が保存済みかどうか示すために渡します。 1037 1038<code>true</code> の場合、{@link android.preference.Preference} クラスの {@code getPersisted*()} メソッド(整数用の {@link android.preference.Preference#getPersistedInt getPersistedInt()} など)のいずれかを呼び出して保存されている値を取得する必要があります。 1039 1040 1041通常は保存されている値を取得するのは、UI を更新して以前保存した値を反映させるためです。 1042 1043</p> 1044 1045<p><code>restorePersistedValue</code> が <code>false</code> の場合、2 番目の引数で渡されたデフォルト値を使用する必要があります。 1046</p> 1047 1048<pre> 1049@Override 1050protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { 1051 if (restorePersistedValue) { 1052 // Restore existing state 1053 mCurrentValue = this.getPersistedInt(DEFAULT_VALUE); 1054 } else { 1055 // Set default state from the XML attribute 1056 mCurrentValue = (Integer) defaultValue; 1057 persistInt(mCurrentValue); 1058 } 1059} 1060</pre> 1061 1062<p>各 {@code getPersisted*()} メソッドは、値が保存されていない場合またはキーが存在しない場合に使用するデフォルト値を指定する引数を取ります。 1063上記の例では、{@link android.preference.Preference#getPersistedInt getPersistedInt()} が保存されている値を返すことができない場合に備えて、ローカル定数がデフォルト値を指定するために使用されています。 1064 1065</p> 1066 1067<p class="caution"><strong>警告:</strong> <code>defaultValue</code> は、<code>restorePersistedValue</code> が <code>true</code> の場合、常に null になるため、{@code getPersisted*()} メソッドでデフォルト値として使用<strong>できません</strong>。 1068 1069</p> 1070 1071 1072<h3 id="CustomDefault">デフォルト値を提供する</h3> 1073 1074<p>{@link android.preference.Preference} クラスのインスタンスがデフォルト値を指定している場合({@code android:defaultValue} 属性を使用)、システムは、オブジェクトのインスタンスを作成するときに {@link android.preference.Preference#onGetDefaultValue onGetDefaultValue()} を呼び出してデフォルト値を取得します。 1075 1076 1077システムでデフォルト値を {@link android.content.SharedPreferences} に保存するには、このメソッドを実装する必要があります。 1078 1079次に例を示します。</p> 1080 1081<pre> 1082@Override 1083protected Object onGetDefaultValue(TypedArray a, int index) { 1084 return a.getInteger(index, DEFAULT_VALUE); 1085} 1086</pre> 1087 1088<p>このメソッドは、属性の配列と取得する必要がある {@code android:defaultValue} のインデックス位置を提供しており、これらはデフォルト値を保存するために必要な情報のすべてです。 1089属性からデフォルト値を抽出するためにこのメソッドの実装が必要なのは、デフォルト値が定義されていないときのために属性のローカル デフォルト値を指定する必要があるためです。 1090 1091</p> 1092 1093 1094 1095<h3 id="CustomSaveState">プリファレンスの状態を保存し復元する</h3> 1096 1097<p>レイアウトの {@link android.view.View} と同じく、{@link android.preference.Preference} サブクラスは、アクティビティやフラグメントが再開される場合(ユーザーが画面を回転させた場合など)に状態の保存と復元を担当します。 1098 1099{@link android.preference.Preference} クラスの状態を適切に保存し復元するには、ライフサイクル コールバック メソッドの {@link android.preference.Preference#onSaveInstanceState onSaveInstanceState()} と {@link android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} を実装する必要があります。 1100 1101 1102 1103</p> 1104 1105<p>{@link android.preference.Preference} の状態は、{@link android.os.Parcelable} インターフェースを実装するオブジェクトによって定義されます。 1106Android フレームワークでは、このようなオブジェクトである{@link android.preference.Preference.BaseSavedState} クラスが状態オブジェクトを定義するための起点として提供されています。 1107 1108</p> 1109 1110<p>{@link android.preference.Preference} クラスが状態を保存する方法を定義するには、{@link android.preference.Preference.BaseSavedState} クラスを継承する必要があります。 1111いくつかのメソッドをオーバーライドして {@link android.preference.Preference.BaseSavedState#CREATOR} オブジェクトを定義してください。 1112 1113</p> 1114 1115<p>大部分のアプリでは、次の実装をコピーして、{@link android.preference.Preference} サブクラスが整数以外のデータ型のデータを保存している場合は、{@code value} を処理している行を変更するだけで使用できます。 1116 1117</p> 1118 1119<pre> 1120private static class SavedState extends BaseSavedState { 1121 // Member that holds the setting's value 1122 // Change this data type to match the type saved by your Preference 1123 int value; 1124 1125 public SavedState(Parcelable superState) { 1126 super(superState); 1127 } 1128 1129 public SavedState(Parcel source) { 1130 super(source); 1131 // Get the current preference's value 1132 value = source.readInt(); // Change this to read the appropriate data type 1133 } 1134 1135 @Override 1136 public void writeToParcel(Parcel dest, int flags) { 1137 super.writeToParcel(dest, flags); 1138 // Write the preference's value 1139 dest.writeInt(value); // Change this to write the appropriate data type 1140 } 1141 1142 // Standard creator object using an instance of this class 1143 public static final Parcelable.Creator<SavedState> CREATOR = 1144 new Parcelable.Creator<SavedState>() { 1145 1146 public SavedState createFromParcel(Parcel in) { 1147 return new SavedState(in); 1148 } 1149 1150 public SavedState[] newArray(int size) { 1151 return new SavedState[size]; 1152 } 1153 }; 1154} 1155</pre> 1156 1157<p>{@link android.preference.Preference.BaseSavedState} の上記の実装をアプリに追加(通常、{@link android.preference.Preference} サブクラスのサブクラスとして追加)するとともに、{@link android.preference.Preference} サブクラスの {@link android.preference.Preference#onSaveInstanceState onSaveInstanceState()} と {@link android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} を実装する必要があります。 1158 1159 1160 1161 1162</p> 1163 1164<p>次に例を示します。</p> 1165 1166<pre> 1167@Override 1168protected Parcelable onSaveInstanceState() { 1169 final Parcelable superState = super.onSaveInstanceState(); 1170 // Check whether this Preference is persistent (continually saved) 1171 if (isPersistent()) { 1172 // No need to save instance state since it's persistent, 1173 // use superclass state 1174 return superState; 1175 } 1176 1177 // Create instance of custom BaseSavedState 1178 final SavedState myState = new SavedState(superState); 1179 // Set the state's value with the class member that holds current 1180 // setting value 1181 myState.value = mNewValue; 1182 return myState; 1183} 1184 1185@Override 1186protected void onRestoreInstanceState(Parcelable state) { 1187 // Check whether we saved the state in onSaveInstanceState 1188 if (state == null || !state.getClass().equals(SavedState.class)) { 1189 // Didn't save the state, so call superclass 1190 super.onRestoreInstanceState(state); 1191 return; 1192 } 1193 1194 // Cast state to custom BaseSavedState and pass to superclass 1195 SavedState myState = (SavedState) state; 1196 super.onRestoreInstanceState(myState.getSuperState()); 1197 1198 // Set this Preference's widget to reflect the restored state 1199 mNumberPicker.setValue(myState.value); 1200} 1201</pre> 1202 1203