• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Configurações
2page.tags=preferência,preferenceactivity,preferencefragment
3
4@jd:body
5
6
7<div id="qv-wrapper">
8<div id="qv">
9
10<h2>Neste documento</h2>
11<ol>
12  <li><a href="#Overview">Visão geral</a>
13    <ol>
14      <li><a href="#SettingTypes">Preferências</a></li>
15    </ol>
16  </li>
17  <li><a href="#DefiningPrefs">Definição de preferências em XML</a>
18    <ol>
19      <li><a href="#Groups">Criação de grupos de configuração</a></li>
20      <li><a href="#Intents">Uso de intenções</a></li>
21    </ol>
22  </li>
23  <li><a href="#Activity">Criação de uma atividade de preferência</a></li>
24  <li><a href="#Fragment">Uso de fragmentos de preferência</a></li>
25  <li><a href="#Defaults">Configuração de valores padrão</a></li>
26  <li><a href="#PreferenceHeaders">Uso de cabeçalhos de preferência</a>
27    <ol>
28      <li><a href="#CreateHeaders">Criação do arquivo de cabeçalhos</a></li>
29      <li><a href="#DisplayHeaders">Exibição de cabeçalhos</a></li>
30      <li><a href="#BackCompatHeaders">Compatibilidade de versões mais antigas com cabeçalhos de preferência</a></li>
31    </ol>
32  </li>
33  <li><a href="#ReadingPrefs">Leitura de preferências</a>
34    <ol>
35      <li><a href="#Listening">Escuta de alterações de preferência</a></li>
36    </ol>
37  </li>
38  <li><a href="#NetworkUsage">Gerenciamento de uso de rede</a></li>
39  <li><a href="#Custom">Composição de uma preferência personalizada</a>
40    <ol>
41      <li><a href="#CustomSelected">Especificação da interface do usuário</a></li>
42      <li><a href="#CustomSave">Salvamento do valor da configuração</a></li>
43      <li><a href="#CustomInitialize">Inicialização do valor atual</a></li>
44      <li><a href="#CustomDefault">Fornecimento de um valor padrão</a></li>
45      <li><a href="#CustomSaveState">Salvamento e restauração do estado da preferência</a></li>
46    </ol>
47  </li>
48</ol>
49
50<h2>Classes principais</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>Veja também</h2>
59<ol>
60  <li><a href="{@docRoot}design/patterns/settings.html">Guia de projeto de configurações</a></li>
61</ol>
62</div>
63</div>
64
65
66
67
68<p>Geralmente os aplicativos contêm configurações que permitem aos usuários modificar características e comportamentos do aplicativo. Por
69exemplo: alguns aplicativos permitem aos usuários especificar se as notificações estão ativadas ou especificar a frequência
70com que o aplicativo sincroniza dados com a nuvem.</p>
71
72<p>Para fornecer configurações ao aplicativo, é preciso usar
73as APIs {@link android.preference.Preference} do Android para programar uma interface coerente
74com a experiência do usuário em outros aplicativos Android (inclusive as configurações do sistema). Este documento descreve
75como programar as configurações do aplicativo por meio de APIs {@link android.preference.Preference}.</p>
76
77<div class="note design">
78<p><strong>Projeto de configurações</strong></p>
79  <p>Para obter mais informações sobre o projeto de configurações, leia o guia de projeto <a href="{@docRoot}design/patterns/settings.html">Configurações</a>.</p>
80</div>
81
82
83<img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" />
84<p class="img-caption"><strong>Figura 1.</strong> Capturas de tela das configurações do aplicativo Mensagens
85do Android. A seleção de um item definido por uma {@link android.preference.Preference}
86abre uma interface para alterar a configuração.</p>
87
88
89
90
91<h2 id="Overview">Visão geral</h2>
92
93<p>Em vez de usar objetos {@link android.view.View} para criar a interface do usuário, as configurações
94são criadas por meio de várias subclasses da classe {@link android.preference.Preference}
95declaradas em um arquivo XML.</p>
96
97<p>Os objetos {@link android.preference.Preference} são as peças fundamentais de uma única
98configuração. Cada {@link android.preference.Preference} aparece como um item em uma lista e oferece a IU
99adequada para que os usuários modifiquem a configuração. Por exemplo: uma {@link
100android.preference.CheckBoxPreference} cria um item de lista que exibe uma caixa de seleção e uma {@link
101android.preference.ListPreference} cria um item que abre uma caixa de diálogo com uma lista de opções.</p>
102
103<p>Cada {@link android.preference.Preference} adicionada tem um par de valor-chave correspondente
104que o sistema usa para salvar a configuração em um arquivo
105{@link android.content.SharedPreferences} padrão para as configurações do aplicativo. Quando o usuário altera uma configuração, o sistema atualiza o valor
106correspondente no arquivo {@link android.content.SharedPreferences}. O único momento em que
107se deve interagir diretamente com o arquivo {@link android.content.SharedPreferences} associado
108é no momento de ler o valor para determinar o comportamento do aplicativo com base na configuração do usuário.</p>
109
110<p>O valor salvo em {@link android.content.SharedPreferences} para cada configuração pode ser
111um dos seguintes tipos de dados:</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>Como a IU de configurações do aplicativo é criada com objetos {@link android.preference.Preference}
123 em vez de objetos
124{@link android.view.View}, é preciso usar uma subclasse {@link android.app.Activity} ou
125{@link android.app.Fragment} especializada para exibir as configurações de lista:</p>
126
127<ul>
128  <li>Se o aplicativo for compatível com versões do Android anteriores à 3.0 (nível da API 10 ou anterior), será
129necessário criar a atividade como uma extensão da classe {@link android.preference.PreferenceActivity}.</li>
130  <li>No Android 3.0 ou versões posteriores, deve-se usar um {@link android.app.Activity} tradicional
131que hospeda um {@link android.preference.PreferenceFragment} que exige as configurações do aplicativo.
132No entanto, pode-se também usar {@link android.preference.PreferenceActivity} para criar um layout de dois painéis
133para telas maiores quando há vários grupos de configurações.</li>
134</ul>
135
136<p>Veja como configurar a {@link android.preference.PreferenceActivity} e instâncias de {@link
137android.preference.PreferenceFragment} nas seções sobre a <a href="#Activity">Criação de uma atividade de preferência</a> e <a href="#Fragment">Uso
138de fragmentos de preferência</a>.</p>
139
140
141<h3 id="SettingTypes">Preferências</h3>
142
143<p>Toda configuração do aplicativo é representada por uma subclasse específica da classe {@link
144android.preference.Preference}. Cada subclasse contém um conjunto de propriedades essenciais que permitem
145especificar itens como o título da configuração e o valor padrão. Cada subclasse também oferece
146suas propriedades e interface do usuário especializadas. Por exemplo: a figura 1 ilustra uma captura de tela
147das configurações do aplicativo Mensagens. Cada item de lista na tela de configurações tem, como fundo, um objeto {@link
148android.preference.Preference} diferente.</p>
149
150<p>A seguir há algumas das preferências mais comuns:</p>
151
152<dl>
153  <dt>{@link android.preference.CheckBoxPreference}</dt>
154  <dd>Exibe um item com uma caixa de seleção para uma configuração que esteja ativada ou desativada. O valor
155salvo é um booleano (<code>true</code> se estiver selecionada).</dd>
156
157  <dt>{@link android.preference.ListPreference}</dt>
158  <dd>Abre uma caixa de diálogo com uma lista de botões de opção. O valor salvo
159pode ser qualquer um dos tipos de valor compatíveis (listados acima).</dd>
160
161  <dt>{@link android.preference.EditTextPreference}</dt>
162  <dd>Abre uma caixa de diálogo com um widget {@link android.widget.EditText}. O valor salvo é um {@link
163java.lang.String}.</dd>
164</dl>
165
166<p>Consulte a classe {@link android.preference.Preference} para ver uma lista de todas as outras subclasses e
167as propriedades correspondentes.</p>
168
169<p>É claro que as classes embutidas não acomodam todas as necessidades e o aplicativo pode exigir
170algo mais especializado. Por exemplo: a plataforma atualmente não fornece nenhuma classe {@link
171android.preference.Preference} para selecionar um número ou data. Portanto, pode ser necessário definir
172a própria subclasse {@link android.preference.Preference}. Veja mais informações na seção sobre <a href="#Custom">Composição de uma preferência personalizada</a>.</p>
173
174
175
176<h2 id="DefiningPrefs">Definição de preferências em XML</h2>
177
178<p>Embora se possa instanciar novos objetos {@link android.preference.Preference} em tempo de execução,
179deve-se definir uma lista de configurações no XML com uma hierarquia
180de objetos {@link android.preference.Preference}. Recomenda-se o uso de um arquivo XML para definir a coleção de configurações porque o arquivo
181oferece uma estrutura fácil de ler e simples de atualizar. Além disso, as configurações do aplicativo
182geralmente são predeterminadas, embora ainda seja possível modificar a coleção em tempo de execução.</p>
183
184<p>Cada subclasse {@link android.preference.Preference} pode ser declarada com um elemento XML
185correspondente ao nome da classe, como {@code &lt;CheckBoxPreference&gt;}.</p>
186
187<p>É preciso salvar o arquivo XML no diretório {@code res/xml/}. Embora seja possível nomear livremente
188o arquivo, é mais frequente vê-lo com o nome {@code preferences.xml}. Geralmente só é necessário um arquivo
189porque as ramificações na hierarquia (que abrem sua própria lista de configurações) são declaradas
190por meio de instâncias aninhadas de {@link android.preference.PreferenceScreen}.</p>
191
192<p class="note"><strong>Observação:</strong> se você deseja criar um layout de vários painéis
193para as configurações, serão necessários arquivos XML separados para cada fragmento.</p>
194
195<p>O nó raiz do arquivo XML deve ser um elemento {@link android.preference.PreferenceScreen
196&lt;PreferenceScreen&gt;}. É dentro desse elemento que se adiciona cada {@link
197android.preference.Preference}. Cada filho adicionado dentro do elemento
198{@link android.preference.PreferenceScreen &lt;PreferenceScreen&gt;} é exibido com um item
199único na lista de configurações.</p>
200
201<p>Por exemplo:</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>Nesse exemplo, existe um {@link android.preference.CheckBoxPreference} e um {@link
223android.preference.ListPreference}. Os dois itens contêm estes três atributos:</p>
224
225<dl>
226  <dt>{@code android:key}</dt>
227  <dd>Esse atributo é necessário para preferências que persistem a um valor de dados. Ele especifica a chave
228exclusiva (uma string) que o sistema usa ao salvar o valor dessa configuração em {@link
229android.content.SharedPreferences}.
230  <p>As únicas instâncias em que esse atributo é <em>dispensável</em> ocorrem quando a preferência é um
231{@link android.preference.PreferenceCategory} ou {@link android.preference.PreferenceScreen},
232ou quando a preferência especifica um {@link android.content.Intent} para invocar (com um elemento <a href="#Intents">{@code &lt;intent&gt;}</a>) ou um {@link android.app.Fragment} para exibir (com um atributo <a href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code
233android:fragment}</a>).</p>
234  </dd>
235  <dt>{@code android:title}</dt>
236  <dd>Fornece à configuração um nome visível ao usuário.</dd>
237  <dt>{@code android:defaultValue}</dt>
238  <dd>Especifica o valor inicial que o sistema deve definir no arquivo {@link
239android.content.SharedPreferences}. Deve-se fornecer um valor padrão para
240todas as configurações.</dd>
241</dl>
242
243<p>Para mais informações sobre todos os outros atributos compatíveis, consulte a documentação {@link
244android.preference.Preference} (e subclasse respectiva).</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>Figura 2.</strong> Definição de categorias
250com títulos. <br/><b>1.</b> A categoria é especificada pelo elemento {@link
251android.preference.PreferenceCategory &lt;PreferenceCategory&gt;}. <br/><b>2.</b> O título
252é especificado com o atributo {@code android:title}.</p>
253</div>
254
255
256<p>Quando a lista de configurações excede cerca de 10 itens, pode ser necessário adicionar títulos
257para definir grupos de configurações ou exibir esses grupos
258em uma tela separada. Essas opções são descritas nas seções a seguir.</p>
259
260
261<h3 id="Groups">Criação de grupos de configuração</h3>
262
263<p>Se você apresentar uma lista de 10 ou mais configurações,
264os usuários podem ter dificuldade de percorrê-las, compreendê-las e processá-las. Para solucionar isso,
265pode-se dividir algumas ou todas as configurações em grupos, transformando uma longa lista
266em várias listas mais curtas. Um grupo de configurações relacionadas pode ser apresentado de uma das seguintes formas:</p>
267
268<ul>
269  <li><a href="#Titles">Uso de títulos</a></li>
270  <li><a href="#Subscreens">Uso de subtelas</a></li>
271</ul>
272
273<p>Pode-se usar uma ou ambas as técnicas de agrupamento para organizar as configurações do aplicativo. Ao decidir
274qual delas usar e como dividir as configurações, deve-se seguir as diretrizes do guia
275<a href="{@docRoot}design/patterns/settings.html">Configurações</a> de Projeto do Android.</p>
276
277
278<h4 id="Titles">Uso de títulos</h4>
279
280<p>Para usar divisores com cabeçalhos entre grupos de configurações (como ilustrado na figura 2),
281coloca-se cada grupo de objetos {@link android.preference.Preference} dentro de {@link
282android.preference.PreferenceCategory}.</p>
283
284<p>Por exemplo:</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">Uso de subtelas</h4>
313
314<p>Para usar grupos de configurações em uma subtela (como ilustrado na figura 3), coloque o grupo
315de objetos {@link android.preference.Preference} dentro de {@link
316android.preference.PreferenceScreen}.</p>
317
318<img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" />
319<p class="img-caption"><strong>Figura 3.</strong> Subtelas de configuração. O elemento {@code
320&lt;PreferenceScreen&gt;} cria
321um item que, quando selecionado, abre uma lista separada para exibir as configurações aninhadas.</p>
322
323<p>Por exemplo:</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">Uso de intenções</h3>
354
355<p>Em alguns casos, pode ser necessário que um item de preferência abra em um atividade diferente
356e não na tela de configuração, como um navegador da web para exibir uma página da web. Para invocar um {@link
357android.content.Intent} quando o usuário seleciona um item de preferência, adicione um elemento {@code &lt;intent&gt;}
358como filho do elemento {@code &lt;Preference&gt;} correspondente.</p>
359
360<p>Por exemplo, a seguir apresenta-se como usar um item de preferência para abrir uma página da web:</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>É possível criar intenções implícitas e explícitas usando os seguintes atributos:</p>
370
371<dl>
372  <dt>{@code android:action}</dt>
373    <dd>A ação a atribuir, conforme o método {@link android.content.Intent#setAction setAction()}.
374</dd>
375  <dt>{@code android:data}</dt>
376    <dd>Os dados a atribuir, conforme o método {@link android.content.Intent#setData setData()}.</dd>
377  <dt>{@code android:mimeType}</dt>
378    <dd>O tipo MIME atribuir, conforme o método {@link android.content.Intent#setType setType()}.
379</dd>
380  <dt>{@code android:targetClass}</dt>
381    <dd>A parte de classe do nome do componente, conforme o método {@link android.content.Intent#setComponent
382setComponent()}.</dd>
383  <dt>{@code android:targetPackage}</dt>
384    <dd>A parte de pacote do nome do componente, conforme o método {@link
385android.content.Intent#setComponent setComponent()}.</dd>
386</dl>
387
388
389
390<h2 id="Activity">Criação de uma atividade de preferência</h2>
391
392<p>Para exibir as configurações em uma atividade, estenda a classe {@link
393android.preference.PreferenceActivity}. É uma extensão da classe tradicional {@link
394android.app.Activity} que exibe uma lista de configurações com base em uma hierarquia de objetos {@link
395android.preference.Preference}. A {@link android.preference.PreferenceActivity}
396automaticamente persiste às configurações associadas a cada {@link
397android.preference.Preference} quando o usuário faz uma alteração.</p>
398
399<p class="note"><strong>Observação:</strong> ao desenvolver um aplicativo para Android 3.0
400ou superior, deve-se usar o {@link android.preference.PreferenceFragment}. Consulte a próxima
401seção sobre o <a href="#Fragment">Uso de fragmentos de preferência</a>.</p>
402
403<p>O mais importante é não carregar um layout de vistas durante o retorno de chamada {@link
404android.preference.PreferenceActivity#onCreate onCreate()}. Em vez disso, chama-se {@link
405android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()}
406para adicionar à atividade as preferências declaradas em um arquivo XML. Por exemplo: abaixo há o código mínimo
407necessário para um {@link android.preference.PreferenceActivity} funcional:</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>Na verdade, esse código é suficiente para alguns aplicativos porque, assim que o usuário modifica uma preferência,
420o sistema salva as alterações em um arquivo padrão {@link android.content.SharedPreferences}
421que os componentes do outro aplicativo poderá ler quando for necessário verificar as configurações do usuário. No entanto,
422muitos aplicativos exigem um pouco mais de código para escutar as alterações que ocorrem nas preferências.
423Para informações sobre a escuda de alterações no arquivo {@link android.content.SharedPreferences},
424consulte a seção sobre <a href="#ReadingPrefs">Leitura de preferências</a>.</p>
425
426
427
428
429<h2 id="Fragment">Uso de fragmentos de preferência</h2>
430
431<p>Ao desenvolver para Android 3.0 (nível da API 11) ou versões posteriores, deve-se usar um {@link
432android.preference.PreferenceFragment} para exibir a lista de objetos {@link android.preference.Preference}.
433 Pode-se adicionar um {@link android.preference.PreferenceFragment} a qualquer atividade &mdash; não é
434necessário usar {@link android.preference.PreferenceActivity}.</p>
435
436<p>Os <a href="{@docRoot}guide/components/fragments.html">fragmentos</a> permitem uma arquitetura
437mais flexível para o aplicativo em comparação com o uso de apenas atividades para qualquer
438tipo de atividade criada. Assim, sugerimos usar {@link
439android.preference.PreferenceFragment} para controlar a exibição das configurações em vez de {@link
440android.preference.PreferenceActivity} sempre que possível.</p>
441
442<p>A implementação de {@link android.preference.PreferenceFragment} pode ser tão simples
443quanto definir o método {@link android.preference.PreferenceFragment#onCreate onCreate()} para carregar
444um arquivo de preferências com {@link android.preference.PreferenceFragment#addPreferencesFromResource
445addPreferencesFromResource()}. Por exemplo:</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>É possível adicionar esse fragmento a um {@link android.app.Activity} como se faria com qualquer outro
461{@link android.app.Fragment}. Por exemplo:</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>Observação:</strong> um {@link android.preference.PreferenceFragment} não tem
478seu próprio objeto {@link android.content.Context}. Se for necessário um objeto {@link android.content.Context}
479, é possível chamar {@link android.app.Fragment#getActivity()}. No entanto, tome cuidado para chamar
480{@link android.app.Fragment#getActivity()} somente quando o fragmento estiver anexado a uma atividade. Quando
481o fragmento ainda não estiver anexado, ou tiver sido separado durante o fim do seu ciclo de vida, {@link
482android.app.Fragment#getActivity()} retornará como nulo.</p>
483
484
485<h2 id="Defaults">Configuração de valores padrão</h2>
486
487<p>As preferências criadas provavelmente definem alguns comportamentos importantes do aplicativo, portanto
488é necessário inicializar o arquivo {@link android.content.SharedPreferences} associado
489com os valores padrão de cada {@link android.preference.Preference} quando o usuário abre o aplicativo
490pela primeira vez.</p>
491
492<p>A primeira coisa a fazer é especificar o valor padrão de cada objeto {@link
493android.preference.Preference}
494no arquivo XML com o atributo {@code android:defaultValue}. O valor pode ser qualquer tipo de dados
495apropriado para o objeto {@link android.preference.Preference} correspondente. Por
496exemplo:</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>Em seguida, a partir do método {@link android.app.Activity#onCreate onCreate()} na atividade principal
511do aplicativo &mdash; e em qualquer outra atividade pela qual o usuário possa entrar no aplicativo pela
512primeira vez &mdash;, chame {@link android.preference.PreferenceManager#setDefaultValues
513setDefaultValues()}:</p>
514
515<pre>
516PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
517</pre>
518
519<p>Essa chamada durante {@link android.app.Activity#onCreate onCreate()} garante que o aplicativo
520seja adequadamente inicializado com as configurações padrão, que o aplicativo pode precisar ler
521para determinar alguns comportamentos (se, por exemplo, baixará dados enquanto estiver
522em uma rede de celular).</p>
523
524<p>Esse método usa três argumentos:</p>
525<ul>
526  <li>O {@link android.content.Context} do aplicativo.</li>
527  <li>O ID de recurso do arquivo XML de preferências para o qual você deseja definir os valores padrão.</li>
528  <li>Booleano que indica se os valores padrão devem ser definidos mais de uma vez.
529<p>Quando <code>false</code>, o sistema define os valores parão somente se esse método nunca tiver
530sido chamado (ou se {@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES}
531no arquivo de preferências compartilhadas do valor padrão for falso).</p></li>
532</ul>
533
534<p>Enquanto o terceiro argumento estiver definido como <code>false</code>, pode-se chamar esse método com segurança
535toda vez que a atividade iniciar sem substituir as preferências salvas do usuário redefinindo-as
536para os padrões. No entanto, se ele for definido como <code>true</code>, todos os valores anteriores
537serão substituídos pelos padrões.</p>
538
539
540
541<h2 id="PreferenceHeaders">Uso de cabeçalhos de preferência</h2>
542
543<p>Em casos raros, pode ser necessário projetar as configurações de forma que a primeira tela
544exiba somente uma lista de <a href="#Subscreens">subtelas</a> (como as do aplicativo Configurações
545conforme ilustrado nas figuras 4 e 5). Ao desenvolver um projeto desse tipo para Android 3.0 ou versão posterior,
546deve-se usar um novo recurso "cabeçalhos" no Android 3.0 em vez de criar subtelas com elementos
547{@link android.preference.PreferenceScreen} aninhados.</p>
548
549<p>Para criar as configurações com cabeçalhos, é preciso:</p>
550<ol>
551  <li>Separar cada grupo de configurações em instâncias separadas de {@link
552android.preference.PreferenceFragment}. Ou seja, cada grupo de configurações precisa de um arquivo
553XML separado.</li>
554  <li>Criar um arquivo XML de cabeçalhos que lista cada grupo de configurações e declara que fragmento
555contém a lista correspondente de configurações.</li>
556  <li>Estender a classe {@link android.preference.PreferenceActivity} para hospedar as configurações.</li>
557  <li>Implementar o retorno de chamada {@link
558android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} para especificar
559o arquivo de cabeçalhos.</li>
560</ol>
561
562<p>Um grande benefício de usar esse modelo é que {@link android.preference.PreferenceActivity}
563automaticamente apresenta o layout de dois painéis ilustrado na figura 4 ao executar em telas grandes.</p>
564
565<p>Mesmo se o aplicativo for compatível com versões de Android anteriores à 3.0, é possível programar
566o aplicativo para usar {@link android.preference.PreferenceFragment} para uma apresentação em dois painéis
567em dispositivos mais novos e ser compatível com a hierarquia tradicional multitelas
568em dispositivos mais antigos (veja a seção sobre <a href="#BackCompatHeaders">Compatibilidade de versões
569mais antigas com cabeçalhos de preferência</a>).</p>
570
571<img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" />
572<p class="img-caption"><strong>Figura 4.</strong> Layout de dois painéis com cabeçalhos. <br/><b>1.</b> Os cabeçalhos
573são definidos com um arquivo XML de cabeçalhos. <br/><b>2.</b> Cada grupo de configurações é definido por um
574{@link android.preference.PreferenceFragment} especificado por um elemento {@code &lt;header&gt;}
575no arquivo de cabeçalhos.</p>
576
577<img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" />
578<p class="img-caption"><strong>Figura 5.</strong> Um dispositivo celular com cabeçalhos de configuração. Quando
579um item é selecionado o {@link android.preference.PreferenceFragment} associado substitui
580os cabeçalhos.</p>
581
582
583<h3 id="CreateHeaders" style="clear:left">Criação do arquivo de cabeçalhos</h3>
584
585<p>Cada grupo de configurações na lista de cabeçalhos é especificado por um único elemento {@code &lt;header&gt;}
586dentro de um elemento raiz {@code &lt;preference-headers&gt;}. Por exemplo:</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>Com o atributo {@code android:fragment}, cada cabeçalho declara uma instância de {@link
606android.preference.PreferenceFragment} que deve abrir quando o usuário selecionar o cabeçalho.</p>
607
608<p>O elemento {@code &lt;extras&gt;} permite passar os pares de valores-chave para o fragmento em um {@link
609android.os.Bundle}. O fragmento pode recuperar os argumentos chamando {@link
610android.app.Fragment#getArguments()}. Há vários motivos para passar argumentos ao fragmento,
611mas um bom motivo é reutilizar a mesma subclasse de {@link
612android.preference.PreferenceFragment} para cada grupo e usar o argumento para especificar
613o arquivo XML de preferências que o fragmento deve carregar.</p>
614
615<p>Por exemplo, a seguir há um fragmento que pode ser reutilizado em vários grupos de configurações, quando
616cada cabeçalho define um argumento {@code &lt;extra&gt;} com a chave {@code "settings"}:</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">Exibição de cabeçalhos</h3>
637
638<p>Para exibir os cabeçalhos de preferência, é preciso implementar o método de retorno de chamada {@link
639android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} e chamar
640{@link android.preference.PreferenceActivity#loadHeadersFromResource
641loadHeadersFromResource()}. Por exemplo:</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>Quando o usuário seleciona um item de uma lista de cabeçalhos, o sistema abre o {@link
653android.preference.PreferenceFragment} associado.</p>
654
655<p class="note"><strong>Observação:</strong> ao usar cabeçalhos de preferência, a subclasse de {@link
656android.preference.PreferenceActivity} não precisa implementar o método {@link
657android.preference.PreferenceActivity#onCreate onCreate()} porque a única tarefa
658necessária para a atividade é carregar os cabeçalhos.</p>
659
660
661<h3 id="BackCompatHeaders">Compatibilidade de versões mais antigas com cabeçalhos de preferência</h3>
662
663<p>Se o aplicativo for compatível com versões de Android anteriores à 3.0, ainda será possível usar cabeçalhos
664para fornecer um layout em dois painéis ao executar no Android 3.0 e versões posteriores. Basta criar um arquivo XML de preferências
665adicional que usa elementos básicos {@link android.preference.Preference
666&lt;Preference&gt;} que se comportam como os itens de cabeçalho (para uso das versões mais antigas
667do Android).</p>
668
669<p>No entanto, em vez de abrir um novo {@link android.preference.PreferenceScreen}, cada elemento {@link
670android.preference.Preference &lt;Preference&gt;} envia um {@link android.content.Intent}
671ao {@link android.preference.PreferenceActivity} que especifica que arquivo XML de preferência
672carregar.</p>
673
674<p>Por exemplo, abaixo há um arquivo XML de cabeçalhos de preferência usado no Android 3.0
675e posterior ({@code res/xml/preference_headers.xml}):</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>E apresenta-se também um arquivo de preferências que fornece os mesmos cabeçalhos de versões de Android
691mais antigas que a 3.0 ({@code res/xml/preference_headers_legacy.xml}):</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>Como a compatibilidade com {@code &lt;preference-headers&gt;} foi adicionada no Android 3.0, o sistema chama
715{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} em seu {@link
716android.preference.PreferenceActivity} somente ao executar em Androd 3.0 ou posterior. Para carregar
717o arquivo de cabeçalhos de “legado" ({@code preference_headers_legacy.xml}), é preciso verificar a versãodo Android
718e, se a versão for mais antiga que o Android 3.0 ({@link
719android.os.Build.VERSION_CODES#HONEYCOMB}), chama {@link
720android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()}
721para carregar o arquivo de cabeçalho legado. Por exemplo:</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>Depois só resta tratar o {@link android.content.Intent} passado para a atividade
743para identificar que arquivo de preferências carregar. Portanto, para recuperar a ação da intenção e compará-la
744com strings de ações conhecidas usadas nas tags de {@code &lt;intent&gt;} do XML de preferências:</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>Observe que chamadas consecutivas a {@link
768android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()}
769empilharão todas as preferências em uma única lista, portanto certifique-se de que seja chamado somente uma vez, encadeando
770as condições com declarações else-if.</p>
771
772
773
774
775
776<h2 id="ReadingPrefs">Leitura de preferências</h2>
777
778<p>Por padrão, todas as preferências do aplicativo são salvas em um arquivo acessível de qualquer lugar
779dentro do aplicativo chamando o método estático {@link
780android.preference.PreferenceManager#getDefaultSharedPreferences
781PreferenceManager.getDefaultSharedPreferences()}. Isso retorna o objeto {@link
782android.content.SharedPreferences} que contém todos os pares de valores-chave associados
783aos objetos {@link android.preference.Preference} usados em {@link
784android.preference.PreferenceActivity}.</p>
785
786<p>Por exemplo, abaixo apresenta-se como ler um dos valores de preferência de outra atividade
787no aplicativo:</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">Escuta de alterações de preferência</h3>
797
798<p>Há alguns motivos pelos quais pode ser necessário ser notificado assim que o usuário altera
799uma das preferências. Para receber um retorno de chamada quando acontece uma alteração em alguma das preferências,
800implemente a interface {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener
801SharedPreference.OnSharedPreferenceChangeListener} e registre a escuta
802para o objeto {@link android.content.SharedPreferences} chamando {@link
803android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
804registerOnSharedPreferenceChangeListener()}.</p>
805
806<p>A interface tem somente um método de retorno de chamada, {@link
807android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged
808onSharedPreferenceChanged()}, e pode ser mais fácil implementar a interface como parte
809da atividade. Por exemplo:</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>Nesse exemplo, o método verifica se a configuração alterada se destina a uma chave de preferência conhecida. Ele
829chama {@link android.preference.PreferenceActivity#findPreference findPreference()} para obter
830o objeto {@link android.preference.Preference} alterado para que possa modificar o sumário
831do item como uma descrição da seleção do usuário. Ou seja, quando a configuração for uma {@link
832android.preference.ListPreference} ou outra configuração de múltipla escolha, deve-se chamar {@link
833android.preference.Preference#setSummary setSummary()} quando a configuração for alterada para exibir
834o status atual (como a configuração Suspensão mostrada na figura 5).</p>
835
836<p class="note"><strong>Observação:</strong> conforme descrito no documento do Projeto para Android sobre <a href="{@docRoot}design/patterns/settings.html">Configurações</a>, recomendamos atualizar
837o sumário de {@link android.preference.ListPreference} a cada vez que o usuário alterar a preferência
838para descrever a configuração atual.</p>
839
840<p>Para um gerenciamento adequado do ciclo de vida na atividade, recomendamos registrar e remover o registro
841de {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} durante os retornos de chamada de {@link
842android.app.Activity#onResume} e {@link android.app.Activity#onPause} respectivamente:</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>Atenção:</strong> ao chamar {@link
861android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
862registerOnSharedPreferenceChangeListener()}, o gerenciador de preferências
863não armazena atualmente uma referência à escuta. É preciso armazenar uma referência
864forte à escuta, senão ela será suscetível à coleta de lixo. Recomendamos
865manter uma referência à escuta nos dados de instância de um objeto
866que existirá enquanto a escuta for necessária.</p>
867
868<p>Por exemplo: no código a seguir, o autor da chamada não mantém nenhuma
869referência à escuta. Como resultado, a escuta estará sujeita à coleta de lixo
870e falhará futuramente em algum momento indeterminado:</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>Em vez disso, armazene uma referência à escuta nos dados de instância de um objeto
883que existirá enquanto a escuta for necessária:</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">Gerenciamento de uso de rede</h2>
896
897
898<p>A partir do Android 4.0, o aplicativo Configurações do sistema permite aos usuários ver o quanto
899de dados de rede que os aplicativos usam em primeiro e segundo plano. Portanto, os usuários
900podem desativar os dados em segundo plano de aplicativos individuais. Para evitar que os usuários desativem
901o acesso do aplicativo a dados em segundo plano, deve-se usar a conexão de dados de forma eficiente
902e permitir aos usuários refinar o uso de dados do aplicativo por meio das configurações do aplicativo.<p>
903
904<p>Por exemplo: deve-se permitir ao usuário controlar a frequência de sincronização dos dados do aplicativo para
905uploads/downloads somente quando estiver em Wi-Fi, o aplicativo usar dados em deslocamento etc. Com esses
906controles disponíveis para eles, é bem menos provável que os usuários desativem o acesso do aplicativo a dados
907quando eles se aproximam dos limites que definem nas Configurações do sistema porque, em vez disso, podem controlar
908precisamente a quantidade de dados que o aplicativo usa.</p>
909
910<p>Depois de adicionadas as preferências necessárias em {@link android.preference.PreferenceActivity}
911para controlar os hábitos de dados do aplicativo, deve-se adicionar um filtro de intenções para {@link
912android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} no arquivo de manifesto. Por exemplo:</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>Esse filtro de intenções indica ao sistema que se trata da atividade que controla
924o uso de dados do aplicativo. Assim, quando o usuário inspeciona a quantidade de dados que o aplicativo está usando
925no aplicativo Configurações do sistema, um botão <em>Exibir configurações de aplicativo</em> fica disponível e inicia
926{@link android.preference.PreferenceActivity} para que o usuário refine a quantidade de dados que
927o aplicativo usa.</p>
928
929
930
931
932
933
934
935<h2 id="Custom">Composição de uma preferência personalizada</h2>
936
937<p>A estrutura do Android contém uma variedade de subclasses {@link android.preference.Preference} que permitem
938criar uma IU com diferentes tipos de configurações.
939No entanto, pode ser necessário descobrir uma configuração pra a qual não há nenhuma solução embutida,
940como um seletor de números ou seletor de datas. Nesse caso, será preciso criar uma preferência personalizada, estendendo
941a classe {@link android.preference.Preference} ou uma das outras subclasses.</p>
942
943<p>Ao estender a classe {@link android.preference.Preference}, há algumas coisas importantes
944a fazer:</p>
945
946<ul>
947  <li>Especificar a interface do usuário exibida quando o usuário seleciona as configurações.</li>
948  <li>Salvar os valores da configuração conforme apropriado.</li>
949  <li>Inicializar {@link android.preference.Preference} com o valor atual (ou padrão)
950quando ela é exibida.</li>
951  <li>Fornecer o valor padrão quando solicitado pelo sistema.</li>
952  <li>Se {@link android.preference.Preference} fornece sua própria IU (como uma caixa de diálogo, por exemplo), salve
953e restaure o estado para tratar de alterações de ciclo de vida (como quando o usuário gira a tela).</li>
954</ul>
955
956<p>As seções a seguir descrevem como executar cada uma dessas tarefas.</p>
957
958
959
960<h3 id="CustomSelected">Especificação da interface do usuário</h3>
961
962  <p>Se a classe {@link android.preference.Preference} for estendida, será preciso implementar
963{@link android.preference.Preference#onClick()} para definir a ação que ocorre quando
964o usuário a seleciona. No entanto, a maioria das configurações personalizadas estendem {@link android.preference.DialogPreference}
965para exibir uma caixa de diálogo, o que simplifica o procedimento. Quando se estende {@link
966android.preference.DialogPreference}, é preciso chamar {@link
967android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()} na classe
968do construtor para especificar o layout da caixa de diálogo.</p>
969
970  <p>Por exemplo, eis o construtor de um {@link
971android.preference.DialogPreference} personalizado que declara o layout e especifica o texto dos botões padrão
972da caixa de diálogo positiva e negativa:</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">Salvamento do valor da configuração</h3>
992
993<p>Para salvar um valor da configuração a qualquer momento, chame um dos métodos {@code persist*()} da classe {@link
994android.preference.Preference}, como {@link
995android.preference.Preference#persistInt persistInt()} se o valor da configuração for um inteiro
996ou {@link android.preference.Preference#persistBoolean persistBoolean()} para salvar um booleano.</p>
997
998<p class="note"><strong>Observação:</strong> cada {@link android.preference.Preference} pode salvar somente
999um tipo de dados, portanto é preciso usar o método {@code persist*()} adequado para o tipo de dados usado pela
1000{@link android.preference.Preference} personalizada.</p>
1001
1002<p>Quando se opta por persistir, a configuração pode depender da classe {@link
1003android.preference.Preference} estendida. Se {@link
1004android.preference.DialogPreference} for estendida, deve-se persistir o valor somente quando a caixa de diálogo
1005fecha devido a um resultado positivo (o usuário seleciona o botão "OK").</p>
1006
1007<p>Quando uma {@link android.preference.DialogPreference} fecha, o sistema chama o método {@link
1008android.preference.DialogPreference#onDialogClosed onDialogClosed()}. O método contém um argumento
1009booleano que especifica se o resultado do usuário é "positivo" &mdash; se o valor é
1010<code>true</code> e, em seguida, o usuário selecionou o botão positivo e você deve salvar o novo valor. Por
1011exemplo:</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>Nesse exemplo, <code>mNewValue</code> é um membro da classe que retém o valor atual
1024da configuração. A chamada de {@link android.preference.Preference#persistInt persistInt()} salva o valor
1025no arquivo {@link android.content.SharedPreferences} (usando automaticamente a chave
1026especificada no arquivo XML dessa {@link android.preference.Preference}).</p>
1027
1028
1029<h3 id="CustomInitialize">Inicialização do valor atual</h3>
1030
1031<p>Quando o sistema adiciona o {@link android.preference.Preference} à tela, ele chama
1032{@link android.preference.Preference#onSetInitialValue onSetInitialValue()} para notificar
1033se a configuração tem um valor persistido. Se não houver valor persistido, essa chamada fornece
1034o valor padrão.</p>
1035
1036<p>O método {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} passa
1037um booleano, <code>restorePersistedValue</code>, para indicar se um valor já foi persistido
1038para a configuração. Se for <code>true</code>, deve-se recuperar o valor persistindo chamando-se
1039 um dos métodos {@code getPersisted*()} da classe {@link
1040android.preference.Preference}, como {@link
1041android.preference.Preference#getPersistedInt getPersistedInt()} para um valor inteiro. Geralmente
1042se recupera o valor persistido para atualizar adequadamente a IU de forma a refletir
1043o valor salvo anteriormente.</p>
1044
1045<p>Se <code>restorePersistedValue</code> for <code>false</code>, deve-se
1046usar o valor padrão passado no segundo argumento.</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>Cada método {@code getPersisted*()} pega um argumento que especifica o valor
1063padrão a usar caso não haja nenhum valor persistido ou se a chave não existir. No
1064exemplo acima, uma constante local é usada para especificar o valor padrão se {@link
1065android.preference.Preference#getPersistedInt getPersistedInt()} não puder retornar um valor persistido.</p>
1066
1067<p class="caution"><strong>Atenção:</strong> <strong>não</strong> é possível usar
1068<code>defaultValue</code> como valor padrão no método {@code getPersisted*()} porque
1069seu valor é sempre nulo quando <code>restorePersistedValue</code> é <code>true</code>.</p>
1070
1071
1072<h3 id="CustomDefault">Fornecimento de um valor padrão</h3>
1073
1074<p>Se a instância da classe {@link android.preference.Preference} especificar um valor padrão
1075(com o atributo {@code android:defaultValue}),
1076o sistema chama {@link android.preference.Preference#onGetDefaultValue
1077onGetDefaultValue()} quando instancia o objeto para recuperar o valor. É preciso
1078implementar esse método para que o sistema salve o valor padrão em {@link
1079android.content.SharedPreferences}. Por exemplo:</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>Os argumentos do método oferecem todo o necessário: a matriz de atributos e a posição
1089do índice do {@code android:defaultValue}, que é preciso recuperar. É preciso implementar esse método
1090para extrair o valor padrão do atributo porque deve-se especificar um valor padrão
1091local para o atributo caso o valor seja indefinido.</p>
1092
1093
1094
1095<h3 id="CustomSaveState">Salvamento e restauração do estado da preferência</h3>
1096
1097<p>Como um {@link android.view.View} em um layout, a subclasse {@link android.preference.Preference}
1098é responsável por salvar e restaurar seu estado caso a atividade ou fragmento seja
1099reiniciado (como ocorre quando o usuário gira a tela). Para salvar e restaurar
1100adequadamente o estado da classe {@link android.preference.Preference}, é preciso implementar
1101os métodos de retorno de chamada do ciclo de vida {@link android.preference.Preference#onSaveInstanceState
1102onSaveInstanceState()} e {@link
1103android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}.</p>
1104
1105<p>O estado de {@link android.preference.Preference} é definido por um objeto que implementa
1106a interface {@link android.os.Parcelable}. A estrutura do Android fornece esse objeto
1107como um ponto inicial para definir o objeto de estado: a classe {@link
1108android.preference.Preference.BaseSavedState}.</p>
1109
1110<p>Para definir como a classe {@link android.preference.Preference} salva seu estado, deve-se estender
1111a classe {@link android.preference.Preference.BaseSavedState}. É preciso substituir
1112alguns métodos e definir o objeto {@link android.preference.Preference.BaseSavedState#CREATOR}.
1113</p>
1114
1115<p>Na maioria dos aplicativos, é possível copiar a implementação a seguir e simplesmente alterar as linhas
1116que tratam o {@code value} se a subclasse {@link android.preference.Preference} salvar um tipo
1117de dados que não seja um inteiro.</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>Com a implementação acima de {@link android.preference.Preference.BaseSavedState} adicionada
1158ao aplicativo (geralmente como uma subclasse da subclasse {@link android.preference.Preference}),
1159é preciso implementar os métodos {@link android.preference.Preference#onSaveInstanceState
1160onSaveInstanceState()} e {@link
1161android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}
1162da subclasse {@link android.preference.Preference}.</p>
1163
1164<p>Por exemplo:</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