• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &lt;CheckBoxPreference&gt;} などのクラス名と一致する 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 &lt;PreferenceScreen&gt;} 要素にする必要があります。
196この要素内に、各 {@link android.preference.Preference} を追加します。
197{@link android.preference.PreferenceScreen &lt;PreferenceScreen&gt;} 要素内に追加したそれぞれの子は、設定のリストで 1 つのアイテムとして表示されます。
198
199</p>
200
201<p>次に例を示します。</p>
202
203<pre>
204&lt;?xml version="1.0" encoding="utf-8"?>
205&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
206    &lt;CheckBoxPreference
207        android:key="pref_sync"
208        android:title="@string/pref_sync"
209        android:summary="@string/pref_sync_summ"
210        android:defaultValue="true" />
211    &lt;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&lt;/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 &lt;intent&gt;}</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 &lt;PreferenceCategory&gt;} 要素で指定します。
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&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
288    &lt;PreferenceCategory
289        android:title="&#64;string/pref_sms_storage_title"
290        android:key="pref_key_storage_settings">
291        &lt;CheckBoxPreference
292            android:key="pref_key_auto_delete"
293            android:summary="&#64;string/pref_summary_auto_delete"
294            android:title="&#64;string/pref_title_auto_delete"
295            android:defaultValue="false"... />
296        &lt;Preference
297            android:key="pref_key_sms_delete_limit"
298            android:dependency="pref_key_auto_delete"
299            android:summary="&#64;string/pref_summary_delete_limit"
300            android:title="&#64;string/pref_title_sms_delete"... />
301        &lt;Preference
302            android:key="pref_key_mms_delete_limit"
303            android:dependency="pref_key_auto_delete"
304            android:summary="&#64;string/pref_summary_delete_limit"
305            android:title="&#64;string/pref_title_mms_delete" ... />
306    &lt;/PreferenceCategory>
307    ...
308&lt;/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 &lt;PreferenceScreen&gt;} は、選択されると、ネストされた設定を表示するための個別のリストを開くアイテムを作成します。
320
321</p>
322
323<p>次に例を示します。</p>
324
325<pre>
326&lt;PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android">
327    &lt;!-- opens a subscreen of settings -->
328    &lt;PreferenceScreen
329        android:key="button_voicemail_category_key"
330        android:title="&#64;string/voicemail"
331        android:persistent="false">
332        &lt;ListPreference
333            android:key="button_voicemail_provider_key"
334            android:title="&#64;string/voicemail_provider" ... />
335        &lt;!-- opens another nested subscreen -->
336        &lt;PreferenceScreen
337            android:key="button_voicemail_setting_key"
338            android:title="&#64;string/voicemail_settings"
339            android:persistent="false">
340            ...
341        &lt;/PreferenceScreen>
342        &lt;RingtonePreference
343            android:key="button_voicemail_ringtone_key"
344            android:title="&#64;string/voicemail_ringtone_title"
345            android:ringtoneType="notification" ... />
346        ...
347    &lt;/PreferenceScreen>
348    ...
349&lt;/PreferenceScreen>
350</pre>
351
352
353<h3 id="Intents">インテントを使用する</h3>
354
355<p>設定画面ではなく、ウェブページを表示するためのウェブブラウザなどの別のアクティビティを開くプリファレンス アイテムが必要になることもあります。
356ユーザーがプリファレンス アイテムを選択したときに {@link android.content.Intent} が呼び出されるようにするには、対応する {@code &lt;Preference&gt;} 要素の子として {@code &lt;intent&gt;} 要素を追加します。
357
358</p>
359
360<p>たとえば、次の方法で、プリファレンス アイテムを使用してウェブページを開くことができます。</p>
361
362<pre>
363&lt;Preference android:title="@string/prefs_web_page" >
364    &lt;intent android:action="android.intent.action.VIEW"
365            android:data="http://www.example.com" />
366&lt;/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    &#64;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} はどのアクティビティにでも追加できます &mdash; {@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    &#64;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    &#64;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&lt;!-- default value is a boolean -->
500&lt;CheckBoxPreference
501    android:defaultValue="true"
502    ... />
503
504&lt;!-- default value is a string -->
505&lt;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 &lt;header&gt;} 要素で指定された {@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 &lt;preference-headers&gt;} 要素内の単独の {@code &lt;header&gt;} 要素によって指定されます。
586次に例を示します。</p>
587
588<pre>
589&lt;?xml version="1.0" encoding="utf-8"?>
590&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
591    &lt;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    &lt;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        &lt;!-- key/value pairs can be included as arguments for the fragment. -->
600        &lt;extra android:name="someKey" android:value="someHeaderValue" />
601    &lt;/header>
602&lt;/preference-headers>
603</pre>
604
605<p>{@code android:fragment} 属性を使用して、各ヘッダーは、ユーザーがヘッダーを選択したときに開く {@link android.preference.PreferenceFragment} のインスタンスを宣言します。
606</p>
607
608<p>{@code &lt;extras&gt;} 要素を使用すると、キーと値のペアを {@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 &lt;extra&gt;} 引数を定義している場合、複数の設定グループで再利用できます。
616</p>
617
618<pre>
619public static class SettingsFragment extends PreferenceFragment {
620    &#64;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    &#64;Override
646    public void onBuildHeaders(List&lt;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 &lt;Preference&gt;} 要素を使用する追加のプリファレンス XML ファイルを作成することだけです。
665
666
667</p>
668
669<p>新しい {@link android.preference.PreferenceScreen} を開く代わりに、各 {@link android.preference.Preference &lt;Preference&gt;} 要素が、ロードするプリファレンス 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&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
679    &lt;header
680        android:fragment="com.example.prefs.SettingsFragmentOne"
681        android:title="@string/prefs_category_one"
682        android:summary="@string/prefs_summ_category_one" />
683    &lt;header
684        android:fragment="com.example.prefs.SettingsFragmentTwo"
685        android:title="@string/prefs_category_two"
686        android:summary="@string/prefs_summ_category_two" />
687&lt;/preference-headers>
688</pre>
689
690<p>また、以下は Android 3.0 よりも前のバージョンに同じヘッダーを提供するプリファレンス ファイル({@code res/xml/preference_headers_legacy.xml})です。
691</p>
692
693<pre>
694&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
695    &lt;Preference
696        android:title="@string/prefs_category_one"
697        android:summary="@string/prefs_summ_category_one"  >
698        &lt;intent
699            android:targetPackage="com.example.prefs"
700            android:targetClass="com.example.prefs.SettingsActivity"
701            android:action="com.example.prefs.PREFS_ONE" />
702    &lt;/Preference>
703    &lt;Preference
704        android:title="@string/prefs_category_two"
705        android:summary="@string/prefs_summ_category_two" >
706        &lt;intent
707            android:targetPackage="com.example.prefs"
708            android:targetClass="com.example.prefs.SettingsActivity"
709            android:action="com.example.prefs.PREFS_TWO" />
710    &lt;/Preference>
711&lt;/PreferenceScreen>
712</pre>
713
714<p>{@code &lt;preference-headers&gt;} のサポートは 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&#64;Override
725public void onCreate(Bundle savedInstanceState) {
726    super.onCreate(savedInstanceState);
727    ...
728
729    if (Build.VERSION.SDK_INT &lt; 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&#64;Override
737public void onBuildHeaders(List&lt;Header> target) {
738   loadHeadersFromResource(R.xml.preference_headers, target);
739}
740</pre>
741
742<p>残りの手順は、アクティビティに渡される {@link android.content.Intent} を処理して、ロードするプリファレンス ファイルを指定するだけです。
743それには、インテントのアクションを取得し、プリファレンス XML の {@code &lt;intent&gt;} タグで使用した既知のアクション文字列と比較します。
744</p>
745
746<pre>
747final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
748...
749
750&#64;Override
751public void onCreate(Bundle savedInstanceState) {
752    super.onCreate(savedInstanceState);
753
754    String action = getIntent().getAction();
755    if (action != null &amp;&amp; action.equals(ACTION_PREFS_ONE)) {
756        addPreferencesFromResource(R.xml.preferences);
757    }
758    ...
759
760    else if (Build.VERSION.SDK_INT &lt; 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&#64;Override
846protected void onResume() {
847    super.onResume();
848    getPreferenceScreen().getSharedPreferences()
849            .registerOnSharedPreferenceChangeListener(this);
850}
851
852&#64;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&lt;activity android:name="SettingsActivity" ... >
916    &lt;intent-filter>
917       &lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
918       &lt;category android:name="android.intent.category.DEFAULT" />
919    &lt;/intent-filter>
920&lt;/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」かどうかを指定するブール値の引数が含まれています &mdash; この値が <code>true</code> の場合はユーザーがポジティブ ボタンを選択しているということであり、新しい値を保存する必要があります。
1009
1010次に例を示します。
1011</p>
1012
1013<pre>
1014&#64;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&#64;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&#64;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    &#64;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&lt;SavedState> CREATOR =
1144            new Parcelable.Creator&lt;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&#64;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&#64;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