| page.title=Настройки |
| page.tags=preference,preferenceactivity,preferencefragment |
| |
| @jd:body |
| |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| <h2>Содержание документа</h2> |
| <ol> |
| <li><a href="#Overview">Обзор</a> |
| <ol> |
| <li><a href="#SettingTypes">Предпочтения</a></li> |
| </ol> |
| </li> |
| <li><a href="#DefiningPrefs">Определение предпочтений в XML</a> |
| <ol> |
| <li><a href="#Groups">Создание групп настроек</a></li> |
| <li><a href="#Intents">Использование намерений</a></li> |
| </ol> |
| </li> |
| <li><a href="#Activity">Создание операции предпочтений</a></li> |
| <li><a href="#Fragment">Использование фрагментов предпочтений</a></li> |
| <li><a href="#Defaults">Значения настроек по умолчанию</a></li> |
| <li><a href="#PreferenceHeaders">Использование заголовков предпочтений</a> |
| <ol> |
| <li><a href="#CreateHeaders">Создание файла заголовков</a></li> |
| <li><a href="#DisplayHeaders">Отображение заголовков</a></li> |
| <li><a href="#BackCompatHeaders">Поддержка старых версий посредством заголовков предпочтений</a></li> |
| </ol> |
| </li> |
| <li><a href="#ReadingPrefs">Чтение предпочтений</a> |
| <ol> |
| <li><a href="#Listening">Отслеживание изменений предпочтений</a></li> |
| </ol> |
| </li> |
| <li><a href="#NetworkUsage">Контроль использования сети</a></li> |
| <li><a href="#Custom">Построение пользовательского предпочтения</a> |
| <ol> |
| <li><a href="#CustomSelected">Указание пользовательского интерфейса</a></li> |
| <li><a href="#CustomSave">Сохранение значения настройки</a></li> |
| <li><a href="#CustomInitialize">Инициализация текущего значения</a></li> |
| <li><a href="#CustomDefault">Предоставление значения по умолчанию</a></li> |
| <li><a href="#CustomSaveState">Сохранение и восстановление состояния предпочтений</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Основные классы</h2> |
| <ol> |
| <li>{@link android.preference.Preference}</li> |
| <li>{@link android.preference.PreferenceActivity}</li> |
| <li>{@link android.preference.PreferenceFragment}</li> |
| </ol> |
| |
| |
| <h2>См. также:</h2> |
| <ol> |
| <li><a href="{@docRoot}design/patterns/settings.html">Руководство по дизайну настроек</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| |
| |
| |
| <p>В приложениях часто содержатся настройки, которые позволяют пользователю изменять возможности и поведение приложения. Например, |
| некоторые приложения позволяют пользователям включать и выключать уведомления или указывать частоту синхронизации |
| данных приложения с облаком.</p> |
| |
| <p>Если вы хотите предоставить настройки для вашего приложения, вы должны использовать |
| API-интерфейсы {@link android.preference.Preference} системы Android для построения интерфейса, согласованного с |
| привычным для пользователей других приложений Android (включая системные настройки). В этом документе показано, |
| как построить настройки вашего приложения посредством API-интерфейсов {@link android.preference.Preference}.</p> |
| |
| <div class="note design"> |
| <p><strong>Дизайн настроек</strong></p> |
| <p>Подробную информацию о дизайне настроек см. в руководстве по дизайну <a href="{@docRoot}design/patterns/settings.html">настроек</a>.</p> |
| </div> |
| |
| |
| <img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" /> |
| <p class="img-caption"><strong>Рисунок 1.</strong> Снимки экранов настроек приложения Android |
| для обмена сообщениями. Выбор элемента, заданного посредством {@link android.preference.Preference}, |
| открывает интерфейс для изменения значения.</p> |
| |
| |
| |
| |
| <h2 id="Overview">Обзор</h2> |
| |
| <p>Вместо использования отображаемых объектов {@link android.view.View} для построения пользовательского интерфейса, настройки создаются |
| с помощью различных подклассов класса {@link android.preference.Preference}, который вы |
| объявляете в XML-файле.</p> |
| |
| <p>Объект {@link android.preference.Preference} является строительным блоком для отдельной |
| настройки. Каждый объект {@link android.preference.Preference} отображается в виде элемента в списке и предоставляет |
| соответствующий пользовательский интерфейс для изменения настройки пользователями. Например, {@link |
| android.preference.CheckBoxPreference} создает элемент списка, который показывает флажок, а {@link |
| android.preference.ListPreference} создает элемент, который открывает диалоговое окно со списком вариантов для выбора.</p> |
| |
| <p>Каждый добавляемый вами объект {@link android.preference.Preference} имеет соответствующую пару «ключ-значение», |
| которую система использует для сохранения настройки в файле {@link android.content.SharedPreferences} |
| значений настроек вашего приложения по умолчанию. Когда пользователь изменяет настройку, система обновляет соответствующее |
| значение в файле {@link android.content.SharedPreferences}. Вам потребуется |
| напрямую взаимодействовать с файлом, связанным с {@link android.content.SharedPreferences}, только в случае, |
| когда нужно прочитать значение для определения поведения вашего приложения на основе пользовательских настроек.</p> |
| |
| <p>Значение, сохраненное в {@link android.content.SharedPreferences} для каждой настройки, может относиться к одному из |
| следующих типов данных:</p> |
| |
| <ul> |
| <li>Логическое значение</li> |
| <li>Число с плавающей точкой</li> |
| <li>Целое число</li> |
| <li>Длинное целое число</li> |
| <li>Строка</li> |
| <li>Строка {@link java.util.Set}</li> |
| </ul> |
| |
| <p>Поскольку пользовательский интерфейс настроек вашего приложения создается посредством объектов {@link android.preference.Preference}, |
| а не |
| объектов {@link android.view.View}, вам потребуется использовать специализированные подклассы {@link android.app.Activity} или |
| {@link android.app.Fragment} для отображения настроек из списка:</p> |
| |
| <ul> |
| <li>Если ваше приложение поддерживает версии Android старше 3.0 (API уровня 10 и ниже), для построения операции |
| необходимо наследовать класс {@link android.preference.PreferenceActivity}.</li> |
| <li>В операционных системах Android 3.0 и более поздних версиях вы должны вместо этого использовать традиционный класс {@link android.app.Activity}, |
| который содержит объект {@link android.preference.PreferenceFragment} для отображения настроек вашего приложения. |
| Однако, когда у вас есть несколько групп настроек, вы можете также |
| использовать {@link android.preference.PreferenceActivity} для создания макета с двумя панелями для больших экранов.</li> |
| </ul> |
| |
| <p>Настройка объекта {@link android.preference.PreferenceActivity} и экземпляров {@link |
| android.preference.PreferenceFragment} описана в разделах <a href="#Activity">Создание операции предпочтения</a> и <a href="#Fragment">Использование |
| фрагментов предпочтений</a>.</p> |
| |
| |
| <h3 id="SettingTypes">Предпочтения</h3> |
| |
| <p>Каждая настройка для вашего приложения представлена конкретным подклассом класса {@link |
| android.preference.Preference}. Каждый подкласс содержит набор основных свойств, которые позволяют вам |
| указывать, например, заголовок для настройки и ее значение по умолчанию. Каждый подкласс также содержит |
| собственные специализированные свойства и пользовательский интерфейс. В качестве примера на рисунке 1 показан снимок экрана настроек |
| приложения Android для обмена сообщениями. Каждый элемент списка на экране настроек возвращается отдельным объектом {@link |
| android.preference.Preference}.</p> |
| |
| <p>Ниже приведены самые распространенные предпочтения:</p> |
| |
| <dl> |
| <dt>{@link android.preference.CheckBoxPreference}</dt> |
| <dd>Отображает элемент с флажком для настройки, которая может быть включена или выключена. Сохраненное |
| значение является логическим (<code>true</code>, если флажок установлен).</dd> |
| |
| <dt>{@link android.preference.ListPreference}</dt> |
| <dd>Открывает диалоговое окно со списком переключателей. Сохраненное значение |
| может относиться к одному из поддерживаемых типов значений (перечисленных выше).</dd> |
| |
| <dt>{@link android.preference.EditTextPreference}</dt> |
| <dd>Открывает диалоговое окно с виджетом {@link android.widget.EditText}. Сохраненное значение — {@link |
| java.lang.String}.</dd> |
| </dl> |
| |
| <p>См. класс {@link android.preference.Preference}, который содержит список всех остальных подклассов и их |
| соответствующих свойств.</p> |
| |
| <p>Конечно, встроенные классы не обеспечивают всех потребностей, и вашему приложению может понадобиться |
| что-либо более специализированное. Например, в настоящее время система не предоставляет класс {@link |
| android.preference.Preference} для выбора числа или даты. Поэтому вам может потребоваться определить |
| свой собственный подкласс {@link android.preference.Preference}. См. раздел <a href="#Custom">Построение пользовательского предпочтения</a>.</p> |
| |
| |
| |
| <h2 id="DefiningPrefs">Определение предпочтений в XML</h2> |
| |
| <p>Хотя вы можете создавать новые экземпляры объектов {@link android.preference.Preference} в режиме выполнения, вы должны |
| определить список настроек в файле XML с иерархией |
| объектов {@link android.preference.Preference}. Использование файла XML для определения вашей коллекции настроек предпочтительней, поскольку файл |
| обладает удобочитаемой структурой, которую легко обновлять. Кроме того, настройки вашего приложения |
| обычно определены заранее, хотя у вас сохраняется возможность изменять коллекцию в режиме выполнения.</p> |
| |
| <p>Каждый подкласс класса {@link android.preference.Preference} может быть объявлен посредством элемента XML, |
| который соответствует имени класса, например, {@code <CheckBoxPreference>}.</p> |
| |
| <p>Вы должны сохранить файл XML в каталоге {@code res/xml/}. Хотя вы можете назвать файл любым |
| именем, традиционно его называют {@code preferences.xml}. Обычно вам требуется лишь один файл, |
| поскольку ветви иерархии (которые открывают собственный список настроек) объявлены с помощью вложенных |
| экземпляров {@link android.preference.PreferenceScreen}.</p> |
| |
| <p class="note"><strong>Примечание.</strong> Если вы хотите создать макет с несколькими панелями для ваших |
| настроек, вам потребуются отдельные файлы XML для каждого фрагмента.</p> |
| |
| <p>Корневой узел XML-файла должен быть элементом {@link android.preference.PreferenceScreen |
| <PreferenceScreen>}. Внутри этого элемента вы добавляете каждый элемент {@link |
| android.preference.Preference}. Каждый дочерний элемент, который вы добавляете внутри элемента |
| {@link android.preference.PreferenceScreen <PreferenceScreen>}, отображается в виде одного |
| пункта в списке настроек.</p> |
| |
| <p>Например:</p> |
| |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
| <CheckBoxPreference |
| android:key="pref_sync" |
| android:title="@string/pref_sync" |
| android:summary="@string/pref_sync_summ" |
| android:defaultValue="true" /> |
| <ListPreference |
| android:dependency="pref_sync" |
| android:key="pref_syncConnectionType" |
| android:title="@string/pref_syncConnectionType" |
| android:dialogTitle="@string/pref_syncConnectionType" |
| android:entries="@array/pref_syncConnectionTypes_entries" |
| android:entryValues="@array/pref_syncConnectionTypes_values" |
| android:defaultValue="@string/pref_syncConnectionTypes_default" /> |
| </PreferenceScreen> |
| </pre> |
| |
| <p>В этом примере есть {@link android.preference.CheckBoxPreference} и {@link |
| android.preference.ListPreference}. Оба содержат следующие три атрибута:</p> |
| |
| <dl> |
| <dt>{@code android:key}</dt> |
| <dd>Этот атрибут необходим для предпочтений, которые сохраняют значение данных. Он задает уникальный |
| ключ (строку), который использует система при сохранении значения этой настройки в {@link |
| android.content.SharedPreferences}. |
| <p>Этот атрибут <em>не является обязательным</em> только когда предпочтение представляет собой |
| {@link android.preference.PreferenceCategory} или {@link android.preference.PreferenceScreen}, либо |
| предпочтение указывает намерение {@link android.content.Intent} для вызова (посредством элемента <a href="#Intents">{@code <intent>}</a>) или фрагмент {@link android.app.Fragment} для отображения (с помощью атрибута <a href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code |
| android:fragment}</a>).</p> |
| </dd> |
| <dt>{@code android:title}</dt> |
| <dd>Этот атрибут предоставляет имя настройки, отображаемое для пользователя.</dd> |
| <dt>{@code android:defaultValue}</dt> |
| <dd>Этот атрибут указывает исходное значение, которое система должна установить в файле {@link |
| android.content.SharedPreferences}. Вы должны указать значения по умолчанию для всех |
| настроек.</dd> |
| </dl> |
| |
| <p>Для получения информации обо всех других поддерживаемых атрибутов см. документацию {@link |
| android.preference.Preference} (и соответствующий подкласс).</p> |
| |
| |
| <div class="figure" style="width:300px"> |
| <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 2.</strong> Создание категорий |
| с заголовками. <br/><b>1.</b> Категория задана элементом {@link |
| android.preference.PreferenceCategory <PreferenceCategory>}. <br/><b>2.</b> Заголовок |
| задан посредством атрибута {@code android:title}.</p> |
| </div> |
| |
| |
| <p>Когда список ваших настроек содержит более 10 элементов, вы, вероятно, захотите добавить заголовки для |
| определения групп настроек или отобразить эти группы |
| на отдельном экране. Эти возможности описаны в следующих разделах.</p> |
| |
| |
| <h3 id="Groups">Создание групп настроек</h3> |
| |
| <p>Если вы представляете список из 10 или более настроек, пользователям |
| может быть трудно их просматривать, воспринимать и обрабатывать. Это можно исправить, |
| разделив некоторые или все настройки на группы, что эффективно преобразует один длинный список в несколько |
| более коротких списков. Группа связанных настроек может быть представлена одним из двух способов:</p> |
| |
| <ul> |
| <li><a href="#Titles">Использование заголовков</a></li> |
| <li><a href="#Subscreens">Использование подэкранов</a></li> |
| </ul> |
| |
| <p>Вы можете пользоваться одним или обоими из этих методов группировки для организации настроек в вашем приложении. Принимая |
| решение об используемом варианте и о разделении настроек на группы, вы должны следовать инструкциям в разделе |
| <a href="{@docRoot}design/patterns/settings.html">Настройки</a> руководства «Дизайн для Android».</p> |
| |
| |
| <h4 id="Titles">Использование заголовков</h4> |
| |
| <p>Если вы хотите создать разделители с заголовками между группами настроек (как показано на рисунке 2), |
| поместите каждую группу объектов {@link android.preference.Preference} внутри {@link |
| android.preference.PreferenceCategory}.</p> |
| |
| <p>Например:</p> |
| |
| <pre> |
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
| <PreferenceCategory |
| android:title="@string/pref_sms_storage_title" |
| android:key="pref_key_storage_settings"> |
| <CheckBoxPreference |
| android:key="pref_key_auto_delete" |
| android:summary="@string/pref_summary_auto_delete" |
| android:title="@string/pref_title_auto_delete" |
| android:defaultValue="false"... /> |
| <Preference |
| android:key="pref_key_sms_delete_limit" |
| android:dependency="pref_key_auto_delete" |
| android:summary="@string/pref_summary_delete_limit" |
| android:title="@string/pref_title_sms_delete"... /> |
| <Preference |
| android:key="pref_key_mms_delete_limit" |
| android:dependency="pref_key_auto_delete" |
| android:summary="@string/pref_summary_delete_limit" |
| android:title="@string/pref_title_mms_delete" ... /> |
| </PreferenceCategory> |
| ... |
| </PreferenceScreen> |
| </pre> |
| |
| |
| <h4 id="Subscreens">Использование подэкранов</h4> |
| |
| <p>Если вы хотите поместить группу настроек на подэкран (как показано на рисунке 3), поместите каждую группу |
| объектов {@link android.preference.Preference} внутри {@link |
| android.preference.PreferenceScreen}.</p> |
| |
| <img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 3.</strong> Создание подэкранов. Элемент {@code |
| <PreferenceScreen>} |
| создает пункт, при выборе которого открывается отдельный список вложенных настроек.</p> |
| |
| <p>Например:</p> |
| |
| <pre> |
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
| <!-- opens a subscreen of settings --> |
| <PreferenceScreen |
| android:key="button_voicemail_category_key" |
| android:title="@string/voicemail" |
| android:persistent="false"> |
| <ListPreference |
| android:key="button_voicemail_provider_key" |
| android:title="@string/voicemail_provider" ... /> |
| <!-- opens another nested subscreen --> |
| <PreferenceScreen |
| android:key="button_voicemail_setting_key" |
| android:title="@string/voicemail_settings" |
| android:persistent="false"> |
| ... |
| </PreferenceScreen> |
| <RingtonePreference |
| android:key="button_voicemail_ringtone_key" |
| android:title="@string/voicemail_ringtone_title" |
| android:ringtoneType="notification" ... /> |
| ... |
| </PreferenceScreen> |
| ... |
| </PreferenceScreen> |
| </pre> |
| |
| |
| <h3 id="Intents">Использование намерений</h3> |
| |
| <p>В некоторых случаях может потребоваться, чтобы элемент предпочтений открывал другую операцию, а не |
| экран настроек, например, веб-браузер для просмотра веб-страницы. Чтобы вызвать {@link |
| android.content.Intent}, когда пользователь выбирает элемент предпочтений, добавьте элемент {@code <intent>} |
| в качестве дочернего элемента соответствующего элемента {@code <Preference>}.</p> |
| |
| <p>Например, здесь показано использование элемента предпочтений для открытия веб-страницы:</p> |
| |
| <pre> |
| <Preference android:title="@string/prefs_web_page" > |
| <intent android:action="android.intent.action.VIEW" |
| android:data="http://www.example.com" /> |
| </Preference> |
| </pre> |
| |
| <p>Вы можете создавать неявные и явные намерения с помощью следующих атрибутов:</p> |
| |
| <dl> |
| <dt>{@code android:action}</dt> |
| <dd>Назначаемое действие, как |
| в методе {@link android.content.Intent#setAction setAction()}.</dd> |
| <dt>{@code android:data}</dt> |
| <dd>Назначаемые данные, как в методе {@link android.content.Intent#setData setData()}.</dd> |
| <dt>{@code android:mimeType}</dt> |
| <dd>Назначаемый тип MIME, как |
| в методе {@link android.content.Intent#setType setType()}.</dd> |
| <dt>{@code android:targetClass}</dt> |
| <dd>Часть имени компонента, означающая класс, как в методе {@link android.content.Intent#setComponent |
| setComponent()}.</dd> |
| <dt>{@code android:targetPackage}</dt> |
| <dd>Пакетная часть имени компонента, как в методе {@link |
| android.content.Intent#setComponent setComponent()}.</dd> |
| </dl> |
| |
| |
| |
| <h2 id="Activity">Создание операции предпочтений</h2> |
| |
| <p>Для отображения ваших настроек в операции наследуйте класс {@link |
| android.preference.PreferenceActivity}. Это наследование традиционного класса {@link |
| android.app.Activity}, который отображает список настроек на основе иерархии объектов {@link |
| android.preference.Preference}. {@link android.preference.PreferenceActivity} |
| автоматически сохраняет настройки, связанные с каждым объектом {@link |
| android.preference.Preference}, когда пользователь вносит изменения.</p> |
| |
| <p class="note"><strong>Примечание.</strong> При разработке приложения для версии Android 3.0 |
| или выше вместо этого следует использовать {@link android.preference.PreferenceFragment}. Прочитайте следующий раздел |
| <a href="#Fragment">Использование фрагментов предпочтений</a>.</p> |
| |
| <p>Запомните самое важное: не загружайте макет отображаемых объектов во время обратного вызова {@link |
| android.preference.PreferenceActivity#onCreate onCreate()}. Вместо этого вызовите {@link |
| android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} для |
| добавления предпочтений, объявленных в XML-файле для операции. Например, здесь приведен |
| минимальный код, необходимый для работы {@link android.preference.PreferenceActivity}:</p> |
| |
| <pre> |
| public class SettingsActivity extends PreferenceActivity { |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| addPreferencesFromResource(R.xml.preferences); |
| } |
| } |
| </pre> |
| |
| <p>Этого кода действительно достаточно для некоторых приложений, поскольку как только пользователь изменяет предпочтение, |
| система сохраняет изменения в файле {@link android.content.SharedPreferences} по умолчанию, который |
| другие компоненты вашего приложения могут читать, когда требуется проверить пользовательские настройки. Однако многим приложениям |
| требуется немного больше кода, чтобы отслеживать изменения, происходящие с предпочтениями. |
| Информацию об отслеживании изменений в файле {@link android.content.SharedPreferences} |
| см. в разделе <a href="#ReadingPrefs">Чтение предпочтений</a>.</p> |
| |
| |
| |
| |
| <h2 id="Fragment">Использование фрагментов предпочтений</h2> |
| |
| <p>При разработке приложений для Android 3.0 (API уровня 11) и более поздних версий необходимо использовать {@link |
| android.preference.PreferenceFragment} для отображения списка |
| объектов {@link android.preference.Preference}. Вы можете добавить {@link android.preference.PreferenceFragment} в любую операцию, при этом |
| необязательно использовать {@link android.preference.PreferenceActivity}.</p> |
| |
| <p><a href="{@docRoot}guide/components/fragments.html">Фрагменты</a> обеспечивают более |
| универсальную архитектуру для вашего приложения по сравнению с использованием отдельных операций, вне зависимости от типа |
| создаваемой операции. Фактически, для управления отображением ваших настроек мы предлагаем вам использовать {@link |
| android.preference.PreferenceFragment} вместо {@link |
| android.preference.PreferenceActivity} при каждой возможности.</p> |
| |
| <p>Ваша реализация {@link android.preference.PreferenceFragment} может содержать просто |
| определение метода {@link android.preference.PreferenceFragment#onCreate onCreate()} для загрузки |
| файла предпочтений посредством {@link android.preference.PreferenceFragment#addPreferencesFromResource |
| addPreferencesFromResource()}. Например:</p> |
| |
| <pre> |
| public static class SettingsFragment extends PreferenceFragment { |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| // Load the preferences from an XML resource |
| addPreferencesFromResource(R.xml.preferences); |
| } |
| ... |
| } |
| </pre> |
| |
| <p>Затем вы можете добавить этот фрагмент в операцию {@link android.app.Activity}, как вы сделали бы это для любого другого фрагмента |
| {@link android.app.Fragment}. Например:</p> |
| |
| <pre> |
| public class SettingsActivity extends Activity { |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| // Display the fragment as the main content. |
| getFragmentManager().beginTransaction() |
| .replace(android.R.id.content, new SettingsFragment()) |
| .commit(); |
| } |
| } |
| </pre> |
| |
| <p class="note"><strong>Примечание.</strong> Фрагмент {@link android.preference.PreferenceFragment} не содержит |
| собственного объекта {@link android.content.Context}. Если вам требуется объект {@link android.content.Context}, |
| вы можете вызвать{@link android.app.Fragment#getActivity()}. Однако разработчик должен быть внимательным и вызывать метод |
| {@link android.app.Fragment#getActivity()} только в том случае, когда фрагмент прикреплен к операции. Если |
| фрагмент еще не прикреплен или был откреплен в конце его жизненного цикла, метод {@link |
| android.app.Fragment#getActivity()} вернет null.</p> |
| |
| |
| <h2 id="Defaults">Установка значений по умолчанию</h2> |
| |
| <p>Вероятно, создаваемые вами предпочтения определяют важное поведение вашего приложения, поэтому |
| необходимо инициализировать соответствующий файл {@link android.content.SharedPreferences}, |
| записав в него значения по умолчанию для каждого предпочтения {@link android.preference.Preference} при первом запуске вашего |
| приложения пользователем.</p> |
| |
| <p>В первую очередь необходимо указать значение по умолчанию для каждого объекта {@link |
| android.preference.Preference} |
| в вашем XML-файле посредством атрибута {@code android:defaultValue}. Значение может относиться к любому |
| типу данных, подходящему для соответствующего объекта {@link android.preference.Preference}. Например: |
| </p> |
| |
| <pre> |
| <!-- default value is a boolean --> |
| <CheckBoxPreference |
| android:defaultValue="true" |
| ... /> |
| |
| <!-- default value is a string --> |
| <ListPreference |
| android:defaultValue="@string/pref_syncConnectionTypes_default" |
| ... /> |
| </pre> |
| |
| <p>Затем из метода {@link android.app.Activity#onCreate onCreate()} основной операции вашего приложения |
| (и из любой другой операции, через которую пользователь может войти в ваше приложение |
| в первый раз) вызовите {@link android.preference.PreferenceManager#setDefaultValues |
| setDefaultValues()}:</p> |
| |
| <pre> |
| PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false); |
| </pre> |
| |
| <p>Вызов этого метода при выполнении {@link android.app.Activity#onCreate onCreate()} гарантирует, что ваше |
| приложение правильно инициализируется и получит настройки по умолчанию, которые могут потребоваться вашему приложению |
| для определенного поведения (например, следует ли загружать данные при работе |
| в сотовой сети).</p> |
| |
| <p>Этот метод имеет три аргумента:</p> |
| <ul> |
| <li>{@link android.content.Context} вашего приложения.</li> |
| <li>Идентификатор ресурса для XML-файла предпочтений, для которого вы хотите установить значения по умолчанию.</li> |
| <li>Логическое значение, которое указывает, требуется ли значения по умолчанию устанавливать более одного раза. |
| <p>При значении <code>false</code> система устанавливает значения по умолчанию только в том случае, если этот метод никогда не вызывался ранее |
| (или атрибут {@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES} |
| в файле общих предпочтений по умолчанию имеет значение false).</p></li> |
| </ul> |
| |
| <p>Когда для третьего аргумента установлено значение <code>false</code>, вы можете вызывать этот метод |
| при каждом запуске операции, не опасаясь перезаписи сохраненных пользовательских предпочтений из-за их сброса в состояние |
| по умолчанию. Однако, если установить для этого аргумента значение <code>true</code>, вы будете перезаписывать все предыдущие |
| значения значениями по умолчанию.</p> |
| |
| |
| |
| <h2 id="PreferenceHeaders">Использование заголовков предпочтений</h2> |
| |
| <p>В редких случаях может потребоваться такая структура настроек, при которой на первом экране отображается только |
| список <a href="#Subscreens">подэкранов</a> (например, как в приложении системных настроек, |
| показанных на рисунках 4 и 5). При разработке такого дизайна для Android 3.0 и более поздних версий вы должны |
| использовать новую возможность Android 3.0 — «заголовки», вместо создания подэкранов посредством вложенных |
| элементов {@link android.preference.PreferenceScreen}.</p> |
| |
| <p>Чтобы создать настройки с заголовками, выполните следующие действия:</p> |
| <ol> |
| <li>Выделите каждую группу настроек в отдельный экземпляр {@link |
| android.preference.PreferenceFragment}. Таким образом, каждая группа настроек должна иметь отдельный |
| XML-файл.</li> |
| <li>Создайте XML-файл заголовков, в котором перечислены все группы настроек и объявления, какой фрагмент |
| содержит соответствующий список настроек.</li> |
| <li>Наследуйте класс {@link android.preference.PreferenceActivity}, который будет содержать ваши настройки.</li> |
| <li>Реализуйте обратный вызов {@link |
| android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()}, чтобы указать |
| файл заголовков.</li> |
| </ol> |
| |
| <p>Огромное преимущество использования этого дизайна состоит в том, что при запуске на больших экранах {@link android.preference.PreferenceActivity} |
| автоматически создает макет с двумя панелями, показанный на рисунке 4.</p> |
| |
| <p>Даже если ваше приложение поддерживает версии Android старше 3.0, вы можете создать |
| приложение, использующее {@link android.preference.PreferenceFragment} для двухпанельного представления на |
| новых устройствах и поддерживающее традиционную многоэкранную иерархию на более старых |
| устройствах (см. раздел <a href="#BackCompatHeaders">Поддержка старых версий посредством |
| заголовков предпочтений</a>).</p> |
| |
| <img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 4.</strong> Двухпанельный макет с заголовками. <br/><b>1.</b> Заголовки |
| определяются посредством XML-файла заголовков. <br/><b>2.</b> Каждая группа настроек определяется с помощью фрагмента |
| {@link android.preference.PreferenceFragment}, который указывается элементом {@code <header>} |
| в файле заголовков.</p> |
| |
| <img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 5.</strong> Смартфон с заголовками настроек. При выборе |
| пункта вместо заголовков отображается соответствующий |
| фрагмент {@link android.preference.PreferenceFragment}.</p> |
| |
| |
| <h3 id="CreateHeaders" style="clear:left">Создание файла заголовков</h3> |
| |
| <p>Каждая группа настроек в вашем списке заголовков указывается отдельным элементом {@code <header>} |
| внутри корневого элемента {@code <preference-headers>}. Например:</p> |
| |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| <preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> |
| <header |
| android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne" |
| android:title="@string/prefs_category_one" |
| android:summary="@string/prefs_summ_category_one" /> |
| <header |
| android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo" |
| android:title="@string/prefs_category_two" |
| android:summary="@string/prefs_summ_category_two" > |
| <!-- key/value pairs can be included as arguments for the fragment. --> |
| <extra android:name="someKey" android:value="someHeaderValue" /> |
| </header> |
| </preference-headers> |
| </pre> |
| |
| <p>Посредством атрибута {@code android:fragment} каждый заголовок объявляет экземпляр фрагмента {@link |
| android.preference.PreferenceFragment}, который должен открываться при выборе этого заголовка пользователем.</p> |
| |
| <p>Элемент {@code <extras>} позволяет передавать пары «ключ-значение» фрагменту в объекте {@link |
| android.os.Bundle}. Фрагмент может извлекать аргументы путем вызова метода {@link |
| android.app.Fragment#getArguments()}. Вы можете передавать аргументы фрагменту по различным причинам, |
| но хорошим поводом является повторное использование одного и того же подкласса {@link |
| android.preference.PreferenceFragment} для каждой группы и использование аргументов для указания |
| XML-файла предпочтений, который должен быть загружен фрагментом.</p> |
| |
| <p>Например, здесь приведен фрагмент, который можно использовать повторно для нескольких групп настроек, когда каждый |
| заголовок определяет аргумент {@code <extra>} с ключом {@code "settings"}:</p> |
| |
| <pre> |
| public static class SettingsFragment extends PreferenceFragment { |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| String settings = getArguments().getString("settings"); |
| if ("notifications".equals(settings)) { |
| addPreferencesFromResource(R.xml.settings_wifi); |
| } else if ("sync".equals(settings)) { |
| addPreferencesFromResource(R.xml.settings_sync); |
| } |
| } |
| } |
| </pre> |
| |
| |
| |
| <h3 id="DisplayHeaders">Отображение заголовков</h3> |
| |
| <p>Чтобы отобразить заголовки предпочтений, вы должны реализовать метод обратного вызова {@link |
| android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} и вызвать |
| {@link android.preference.PreferenceActivity#loadHeadersFromResource |
| loadHeadersFromResource()}. Например:</p> |
| |
| <pre> |
| public class SettingsActivity extends PreferenceActivity { |
| @Override |
| public void onBuildHeaders(List<Header> target) { |
| loadHeadersFromResource(R.xml.preference_headers, target); |
| } |
| } |
| </pre> |
| |
| <p>Когда пользователь выбирает пункт в списке заголовков, система открывает связанный {@link |
| android.preference.PreferenceFragment}.</p> |
| |
| <p class="note"><strong>Примечание.</strong> При использовании заголовков предпочтений ваш подкласс {@link |
| android.preference.PreferenceActivity} не должен реализовывать метод {@link |
| android.preference.PreferenceActivity#onCreate onCreate()}, поскольку единственной обязательной задачей |
| операции является загрузка заголовков.</p> |
| |
| |
| <h3 id="BackCompatHeaders">Поддержка старых версий с заголовками предпочтений</h3> |
| |
| <p>Если ваше приложение поддерживает версии Android старше 3.0, вы можете использовать заголовки для |
| предоставления двухпанельного макета при работе на Android 3.0 или более поздней версии. Достаточно создать |
| дополнительный XML-файл настроек, использующий базовые элементы {@link android.preference.Preference |
| <Preference>}, которые ведут себя аналогично пунктам заголовка (для использования в более старых версиях |
| Android).</p> |
| |
| <p>Вместо открытия новых экранов {@link android.preference.PreferenceScreen} каждый из элементов {@link |
| android.preference.Preference <Preference>} отправляет намерение {@link android.content.Intent} в |
| {@link android.preference.PreferenceActivity} с указанием XML-файла предпочтений |
| для загрузки.</p> |
| |
| <p>В качестве примера приведен XML-файл для заголовков предпочтений, который используется в Android версии 3.0 |
| и более поздних версий ({@code res/xml/preference_headers.xml}):</p> |
| |
| <pre> |
| <preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> |
| <header |
| android:fragment="com.example.prefs.SettingsFragmentOne" |
| android:title="@string/prefs_category_one" |
| android:summary="@string/prefs_summ_category_one" /> |
| <header |
| android:fragment="com.example.prefs.SettingsFragmentTwo" |
| android:title="@string/prefs_category_two" |
| android:summary="@string/prefs_summ_category_two" /> |
| </preference-headers> |
| </pre> |
| |
| <p>А здесь представлен файл предпочтений, который содержит те же самые заголовки для версий старше |
| Android 3.0 ({@code res/xml/preference_headers_legacy.xml}):</p> |
| |
| <pre> |
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
| <Preference |
| android:title="@string/prefs_category_one" |
| android:summary="@string/prefs_summ_category_one" > |
| <intent |
| android:targetPackage="com.example.prefs" |
| android:targetClass="com.example.prefs.SettingsActivity" |
| android:action="com.example.prefs.PREFS_ONE" /> |
| </Preference> |
| <Preference |
| android:title="@string/prefs_category_two" |
| android:summary="@string/prefs_summ_category_two" > |
| <intent |
| android:targetPackage="com.example.prefs" |
| android:targetClass="com.example.prefs.SettingsActivity" |
| android:action="com.example.prefs.PREFS_TWO" /> |
| </Preference> |
| </PreferenceScreen> |
| </pre> |
| |
| <p>Так как поддержка {@code <preference-headers>} была добавлена в версии Android 3.0, система вызывает |
| {@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} в методе {@link |
| android.preference.PreferenceActivity} только при работе в Android версии 3.0 или более поздней версии. Чтобы загрузить |
| «старый» файл заголовков ({@code preference_headers_legacy.xml}), вы должны проверить версию Android |
| и, если версия старше Android 3.0 ({@link |
| android.os.Build.VERSION_CODES#HONEYCOMB}), вызвать {@link |
| android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} для |
| загрузки старого файла заголовков. Например:</p> |
| |
| <pre> |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| ... |
| |
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { |
| // Load the legacy preferences headers |
| addPreferencesFromResource(R.xml.preference_headers_legacy); |
| } |
| } |
| |
| // Called only on Honeycomb and later |
| @Override |
| public void onBuildHeaders(List<Header> target) { |
| loadHeadersFromResource(R.xml.preference_headers, target); |
| } |
| </pre> |
| |
| <p>Остается обработать намерение {@link android.content.Intent}, переданное |
| в операцию, чтобы идентифицировать файл предпочтений для загрузки. Поэтому извлеките операцию намерения и сравните ее |
| с известными строками действия, которые вы использовали в тегах {@code <intent>} XML-файла предпочтений:</p> |
| |
| <pre> |
| final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE"; |
| ... |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| String action = getIntent().getAction(); |
| if (action != null && action.equals(ACTION_PREFS_ONE)) { |
| addPreferencesFromResource(R.xml.preferences); |
| } |
| ... |
| |
| else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { |
| // Load the legacy preferences headers |
| addPreferencesFromResource(R.xml.preference_headers_legacy); |
| } |
| } |
| </pre> |
| |
| <p>При этом помните, что последующие вызовы {@link |
| android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} будут помещать |
| все предпочтения в один список, поэтому обязательно используйте операторы else-if, чтобы обеспечить только |
| однократный вызов метода при изменении условий.</p> |
| |
| |
| |
| |
| |
| <h2 id="ReadingPrefs">Чтение предпочтений</h2> |
| |
| <p>По умолчанию все предпочтения вашего приложения сохраняются в файле, который доступен из любого места |
| вашего приложения посредством вызова статического метода {@link |
| android.preference.PreferenceManager#getDefaultSharedPreferences |
| PreferenceManager.getDefaultSharedPreferences()}. Он возвращает объект {@link |
| android.content.SharedPreferences}, содержащий все пары «ключ-значение», связанные |
| с объектами {@link android.preference.Preference}, использованными в вашей операции {@link |
| android.preference.PreferenceActivity}.</p> |
| |
| <p>В качестве примера показано чтение одного из значений предпочтений из любой другой операции в вашем |
| приложении:</p> |
| |
| <pre> |
| SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); |
| String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, ""); |
| </pre> |
| |
| |
| |
| <h3 id="Listening">Отслеживание изменений предпочтений</h3> |
| |
| <p>Существует несколько причин, по которым вы можете захотеть получать уведомления, как только пользователь изменяет одно из |
| предпочтений. Чтобы получать обратный вызов при изменении любого из предпочтений, |
| реализуйте интерфейс {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener |
| SharedPreference.OnSharedPreferenceChangeListener} и зарегистрируйте приемник для объекта |
| {@link android.content.SharedPreferences} посредством вызова {@link |
| android.content.SharedPreferences#registerOnSharedPreferenceChangeListener |
| registerOnSharedPreferenceChangeListener()}.</p> |
| |
| <p>Этот интерфейс содержит только один метод обратного вызова, {@link |
| android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged |
| onSharedPreferenceChanged()}, и вы, вероятно, сочтете его самым простым способом реализации интерфейса в составе своей |
| операции. Например:</p> |
| |
| <pre> |
| public class SettingsActivity extends PreferenceActivity |
| implements OnSharedPreferenceChangeListener { |
| public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType"; |
| ... |
| |
| public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, |
| String key) { |
| if (key.equals(KEY_PREF_SYNC_CONN)) { |
| Preference connectionPref = findPreference(key); |
| // Set summary to be the user-description for the selected value |
| connectionPref.setSummary(sharedPreferences.getString(key, "")); |
| } |
| } |
| } |
| </pre> |
| |
| <p>В этом примере метод проверяет, выполнено ли изменение настройки для известного ключа предпочтений. Он |
| вызывает {@link android.preference.PreferenceActivity#findPreference findPreference()} для получения объекта |
| {@link android.preference.Preference}, который был изменен, поэтому он может изменить сводку пункта |
| , описывающего выбор пользователя. То есть, когда настройка представляет собой {@link |
| android.preference.ListPreference} или другую настройку с несколькими вариантами выбора, при изменении этой настройки вы должны вызвать {@link |
| android.preference.Preference#setSummary setSummary()} для отображения |
| текущего состояния (например, настройка спящего режима, показанная на рисунке 5).</p> |
| |
| <p class="note"><strong>Примечание.</strong> В соответствии с рекомендациями раздела <a href="{@docRoot}design/patterns/settings.html">Настройки</a> руководства «Дизайн для Android», мы рекомендуем вам обновлять |
| сводку для {@link android.preference.ListPreference} при каждом изменении предпочтения пользователем, |
| чтобы описать текущую настройку.</p> |
| |
| <p>Для правильного управления жизненным циклом в операции мы рекомендуем вам регистрировать или отменять регистрацию |
| вашего приемника {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} во время выполнения обратных вызовов {@link |
| android.app.Activity#onResume} и {@link android.app.Activity#onPause} соответственно:</p> |
| |
| <pre> |
| @Override |
| protected void onResume() { |
| super.onResume(); |
| getPreferenceScreen().getSharedPreferences() |
| .registerOnSharedPreferenceChangeListener(this); |
| } |
| |
| @Override |
| protected void onPause() { |
| super.onPause(); |
| getPreferenceScreen().getSharedPreferences() |
| .unregisterOnSharedPreferenceChangeListener(this); |
| } |
| </pre> |
| |
| <p class="caution"><strong>Внимание!</strong> Когда вы вызываете приемник {@link |
| android.content.SharedPreferences#registerOnSharedPreferenceChangeListener |
| registerOnSharedPreferenceChangeListener()}, диспетчер предпочтений не |
| сохраняет строгую ссылку на приемник. Вы должны сохранить строгую |
| ссылку на приемник, в противном случае она будет чувствительной к очистке памяти. Мы |
| рекомендуем хранить ссылку на приемник в данных экземпляра объекта |
| , который будет существовать, пока вам нужен приемник.</p> |
| |
| <p>Например, в следующем коде вызывающий объект не сохраняет |
| ссылку на приемник. В результате этого приемник будет удален при очистке памяти |
| и через некоторое время приведет к сбою:</p> |
| |
| <pre> |
| prefs.registerOnSharedPreferenceChangeListener( |
| // Bad! The listener is subject to garbage collection! |
| new SharedPreferences.OnSharedPreferenceChangeListener() { |
| public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { |
| // listener implementation |
| } |
| }); |
| </pre> |
| |
| <p>Вместо этого сохраните ссылку на приемник в поле данных экземпляра объекта |
| , который будет существовать, пока нужен приемник:</p> |
| |
| <pre> |
| SharedPreferences.OnSharedPreferenceChangeListener listener = |
| new SharedPreferences.OnSharedPreferenceChangeListener() { |
| public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { |
| // listener implementation |
| } |
| }; |
| prefs.registerOnSharedPreferenceChangeListener(listener); |
| </pre> |
| |
| <h2 id="NetworkUsage">Контроль использования сети</h2> |
| |
| |
| <p>Начиная с версии Android 4.0, системное приложение «Настройки» позволяет пользователям просматривать использование |
| сетевых данных приложениями, работающими на переднем плане и в фоновом режиме. После этого пользователи могут |
| отключить использование данных в фоновом режиме для отдельных приложений. Для того, чтобы пользователи не отключали доступ вашего приложения к данным |
| в фоновом режиме, вы должны эффективно использовать подключение в режиме передачи данных и предоставить |
| пользователям возможность настройки использования данных вашим приложением посредством настроек приложения.<p> |
| |
| <p>Например, вы можете позволить пользователям управлять частотой синхронизации данных приложения, выполнением загрузки |
| только в режиме подключения по Wi-Fi, использованием данных в роуминге и т. д. Когда |
| эти возможности управления доступны, пользователи с меньшей вероятностью отключат доступ вашего приложения к данным, |
| когда оно достигает установленных в системных настройках лимитов, поскольку вместо отключения они могут |
| точно контролировать объем данных, который использует ваше приложение.</p> |
| |
| <p>После добавления необходимых предпочтений в вашу операцию {@link android.preference.PreferenceActivity} |
| для управления поведением вашего приложения в отношении данных вы должны добавить фильтр намерений для {@link |
| android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} в вашем файле манифеста. Например:</p> |
| |
| <pre> |
| <activity android:name="SettingsActivity" ... > |
| <intent-filter> |
| <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" /> |
| <category android:name="android.intent.category.DEFAULT" /> |
| </intent-filter> |
| </activity> |
| </pre> |
| |
| <p>Этот фильтр манифеста указывает системе, что эта операция управляет использованием |
| данных вашим приложением. Так, когда пользователь проверяет объем использованных приложением данных в системном приложении |
| «Настройки», отображается кнопка <em>Просмотреть настройки приложения</em>, которая запускает вашу операцию |
| {@link android.preference.PreferenceActivity}, чтобы пользователь мог уточнить, сколько данных использует |
| ваше приложение.</p> |
| |
| |
| |
| |
| |
| |
| |
| <h2 id="Custom">Построение пользовательского предпочтения</h2> |
| |
| <p>Система Android содержит множество подклассов {@link android.preference.Preference}, которые |
| позволяют вам строить пользовательский интерфейс для нескольких различных типов настроек. |
| Тем не менее, вы можете обнаружить, что для нужной вам настройки нет встроенного решения, например, для выбора |
| числа или даты. В таком случае вам потребуется создать нестандартное предпочтение путем наследования |
| класса {@link android.preference.Preference} или одного из других подклассов.</p> |
| |
| <p>При наследовании класса {@link android.preference.Preference} нужно выполнить несколько |
| важных пунктов:</p> |
| |
| <ul> |
| <li>Укажите пользовательский интерфейс, который должен отображаться при выборе этой настройки пользователем.</li> |
| <li>При необходимости сохраните значение настройки.</li> |
| <li>Инициализируйте {@link android.preference.Preference} текущим значением (или значением по умолчанию), |
| когда предпочтение отображается.</li> |
| <li>Укажите значение по умолчанию в ответ на запрос системы.</li> |
| <li>Если {@link android.preference.Preference} содержит свой собственный пользовательский интерфейс (например, диалоговое окно), сохраните |
| и восстановите состояние для обработки изменений жизненного цикла (например, когда пользователь поворачивает экран).</li> |
| </ul> |
| |
| <p>В следующих разделах описано выполнение каждой из этих задач.</p> |
| |
| |
| |
| <h3 id="CustomSelected">Указание пользовательского интерфейса</h3> |
| |
| <p>Если вы наследуете класс {@link android.preference.Preference} непосредственно, вы должны реализовать метод |
| {@link android.preference.Preference#onClick()}, чтобы задать действие, происходящее при выборе |
| пункта пользователем. Однако большая часть нестандартных настроек наследует {@link android.preference.DialogPreference}, чтобы |
| отобразить диалоговое окно, что упрощает процедуру. Когда вы наследуете {@link |
| android.preference.DialogPreference}, вы должны вызвать {@link |
| android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()}, находясь в конструкторе |
| класса, чтобы указать макет диалогового окна.</p> |
| |
| <p>В качестве примера показан конструктор нестандартного диалогового окна {@link |
| android.preference.DialogPreference}, в котором объявляется макет и указывается текст для |
| положительной и отрицательной кнопок диалога по умолчанию:</p> |
| |
| <pre> |
| public class NumberPickerPreference extends DialogPreference { |
| public NumberPickerPreference(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| |
| setDialogLayoutResource(R.layout.numberpicker_dialog); |
| setPositiveButtonText(android.R.string.ok); |
| setNegativeButtonText(android.R.string.cancel); |
| |
| setDialogIcon(null); |
| } |
| ... |
| } |
| </pre> |
| |
| |
| |
| <h3 id="CustomSave">Сохранение значения настройки</h3> |
| |
| <p>Вы можете сохранить значение настройки в любой момент, вызвав один из методов {@code persist*()} класса {@link |
| android.preference.Preference}, например, {@link |
| android.preference.Preference#persistInt persistInt()}, если настройка имеет целое значение, или |
| {@link android.preference.Preference#persistBoolean persistBoolean()} для сохранения логического значения.</p> |
| |
| <p class="note"><strong>Примечание.</strong> Каждое предпочтение {@link android.preference.Preference} может сохранять только один |
| тип данных, поэтому вы должны использовать метод {@code persist*()}, соответствующий типу данных, используемых вашим |
| пользовательским предпочтением {@link android.preference.Preference}.</p> |
| |
| <p>Выбор метода сохранения настройки может зависеть от наследованного класса {@link |
| android.preference.Preference}. Если вы наследуете {@link |
| android.preference.DialogPreference}, вы должны сохранять значение только при закрытии диалога |
| с положительным результатом (пользователь нажал кнопку «OK»).</p> |
| |
| <p>Когда {@link android.preference.DialogPreference} закрывается, система вызывает метод {@link |
| android.preference.DialogPreference#onDialogClosed onDialogClosed()}. Этот метод содержит |
| логический аргумент, который указывает, является ли результат пользователя «положительным» — если аргумент имеет значение |
| <code>true</code>, значит пользователь выбрал положительную кнопку и вы должны сохранить новое значение. Например: |
| </p> |
| |
| <pre> |
| @Override |
| protected void onDialogClosed(boolean positiveResult) { |
| // When the user selects "OK", persist the new value |
| if (positiveResult) { |
| persistInt(mNewValue); |
| } |
| } |
| </pre> |
| |
| <p>В этом примере <code>mNewValue</code> — это член класса, который содержит текущее значение |
| настройки. При вызове {@link android.preference.Preference#persistInt persistInt()} значение сохраняется |
| в файл {@link android.content.SharedPreferences} (с автоматическим использованием ключа, |
| указанного в XML-файле для этого предпочтения {@link android.preference.Preference}).</p> |
| |
| |
| <h3 id="CustomInitialize">Инициализация текущего значения</h3> |
| |
| <p>Когда система добавляет ваше предпочтение {@link android.preference.Preference} на экран, она |
| вызывает метод {@link android.preference.Preference#onSetInitialValue onSetInitialValue()}, чтобы уведомить вас, |
| имеет ли настройка сохраненное значение. Если сохраненного значения нет, этот вызов предоставляет вам |
| значение по умолчанию.</p> |
| |
| <p>Метод {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} передает |
| логическое значение, <code>restorePersistedValue</code>, чтобы показать, было ли уже сохранено значение |
| для настройки. Если значение равно <code>true</code>, вы должны извлечь сохраненное значение, вызвав |
| один из методов {@code getPersisted*()} класса {@link |
| android.preference.Preference}, например, {@link |
| android.preference.Preference#getPersistedInt getPersistedInt()} для целого значения. Обычно |
| требуется извлечь сохраненное значение, чтобы можно было правильно обновить пользовательский интерфейс для отражения |
| ранее сохраненного значения.</p> |
| |
| <p>Если <code>restorePersistedValue</code> имеет значение <code>false</code>, вы |
| должны использовать значение по умолчанию, которое передается во втором аргументе.</p> |
| |
| <pre> |
| @Override |
| protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { |
| if (restorePersistedValue) { |
| // Restore existing state |
| mCurrentValue = this.getPersistedInt(DEFAULT_VALUE); |
| } else { |
| // Set default state from the XML attribute |
| mCurrentValue = (Integer) defaultValue; |
| persistInt(mCurrentValue); |
| } |
| } |
| </pre> |
| |
| <p>Каждый метод {@code getPersisted*()} содержит аргумент, который указывает |
| значение по умолчанию на случай, когда действительно нет сохраненного значения, или не существует ключ. В |
| приведенном выше примере локальная константа служит для указания значения по умолчанию на случай, если {@link |
| android.preference.Preference#getPersistedInt getPersistedInt()} не может вернуть сохраненное значение.</p> |
| |
| <p class="caution"><strong>Внимание!</strong> Вы <strong>не можете</strong> использовать |
| <code>defaultValue</code> в качестве значения по умолчанию в методе {@code getPersisted*()}, так как |
| его значение всегда равно null, когда <code>restorePersistedValue</code> имеет значение <code>true</code>.</p> |
| |
| |
| <h3 id="CustomDefault">Предоставление значения по умолчанию</h3> |
| |
| <p>Если экземпляр вашего класса {@link android.preference.Preference} указывает значение по умолчанию |
| (с помощью атрибута {@code android:defaultValue}), |
| система вызывает {@link android.preference.Preference#onGetDefaultValue |
| onGetDefaultValue()}, когда она создает экземпляр объекта для извлечения значения. Вы должны реализовать |
| этот метод, чтобы сохранить значение по умолчанию для системы в {@link |
| android.content.SharedPreferences}. Например:</p> |
| |
| <pre> |
| @Override |
| protected Object onGetDefaultValue(TypedArray a, int index) { |
| return a.getInteger(index, DEFAULT_VALUE); |
| } |
| </pre> |
| |
| <p>Аргументы метода предоставляют все необходимое: массив атрибутов и указатель |
| положения {@code android:defaultValue}, который вы должны извлечь. Причина, по которой вы должны |
| реализовать этот метод, чтобы извлечь значение по умолчанию из атрибута, состоит в том, что вы должны указать |
| локальное значение по умолчанию для атрибута в случае, когда значение не определено.</p> |
| |
| |
| |
| <h3 id="CustomSaveState">Сохранение и восстановление состояния предпочтений</h3> |
| |
| <p>Как и {@link android.view.View} в макете, ваш подкласс {@link android.preference.Preference} |
| отвечает за сохранение и восстановление своего состояния в случае перезапуска операции или фрагмента |
| (например, когда пользователь поворачивает экран). Чтобы правильно сохранять и восстанавливать |
| состояние вашего класса {@link android.preference.Preference}, вы должны реализовать |
| методы обратного вызова жизненного цикла {@link android.preference.Preference#onSaveInstanceState |
| onSaveInstanceState()} и {@link |
| android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}.</p> |
| |
| <p>Состояние вашего {@link android.preference.Preference} определяется объектом, который реализует |
| интерфейс {@link android.os.Parcelable}. Система Android предоставляет вам такой объект |
| в качестве начальной точки для определения вашего объекта состояния: класс {@link |
| android.preference.Preference.BaseSavedState}.</p> |
| |
| <p>Чтобы определить, как ваш класс {@link android.preference.Preference} сохраняет свое состояние, вы должны |
| наследовать класс {@link android.preference.Preference.BaseSavedState}. Вы должны переопределить лишь |
| несколько методов и определить объект |
| {@link android.preference.Preference.BaseSavedState#CREATOR}.</p> |
| |
| <p>Для большинства приложений вы можете скопировать следующую реализацию и просто изменить строки, которые |
| обрабатывают {@code value}, если ваш подкласс {@link android.preference.Preference} сохраняет типы |
| данных, отличные от целых.</p> |
| |
| <pre> |
| private static class SavedState extends BaseSavedState { |
| // Member that holds the setting's value |
| // Change this data type to match the type saved by your Preference |
| int value; |
| |
| public SavedState(Parcelable superState) { |
| super(superState); |
| } |
| |
| public SavedState(Parcel source) { |
| super(source); |
| // Get the current preference's value |
| value = source.readInt(); // Change this to read the appropriate data type |
| } |
| |
| @Override |
| public void writeToParcel(Parcel dest, int flags) { |
| super.writeToParcel(dest, flags); |
| // Write the preference's value |
| dest.writeInt(value); // Change this to write the appropriate data type |
| } |
| |
| // Standard creator object using an instance of this class |
| public static final Parcelable.Creator<SavedState> CREATOR = |
| new Parcelable.Creator<SavedState>() { |
| |
| public SavedState createFromParcel(Parcel in) { |
| return new SavedState(in); |
| } |
| |
| public SavedState[] newArray(int size) { |
| return new SavedState[size]; |
| } |
| }; |
| } |
| </pre> |
| |
| <p>После добавления показанной выше реализации {@link android.preference.Preference.BaseSavedState} |
| в ваше приложение (обычно в качестве подкласса вашего подкласса {@link android.preference.Preference}), вам |
| потребуется реализовать методы {@link android.preference.Preference#onSaveInstanceState |
| onSaveInstanceState()} и {@link |
| android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} для вашего |
| подкласса {@link android.preference.Preference}.</p> |
| |
| <p>Например:</p> |
| |
| <pre> |
| @Override |
| protected Parcelable onSaveInstanceState() { |
| final Parcelable superState = super.onSaveInstanceState(); |
| // Check whether this Preference is persistent (continually saved) |
| if (isPersistent()) { |
| // No need to save instance state since it's persistent, |
| // use superclass state |
| return superState; |
| } |
| |
| // Create instance of custom BaseSavedState |
| final SavedState myState = new SavedState(superState); |
| // Set the state's value with the class member that holds current |
| // setting value |
| myState.value = mNewValue; |
| return myState; |
| } |
| |
| @Override |
| protected void onRestoreInstanceState(Parcelable state) { |
| // Check whether we saved the state in onSaveInstanceState |
| if (state == null || !state.getClass().equals(SavedState.class)) { |
| // Didn't save the state, so call superclass |
| super.onRestoreInstanceState(state); |
| return; |
| } |
| |
| // Cast state to custom BaseSavedState and pass to superclass |
| SavedState myState = (SavedState) state; |
| super.onRestoreInstanceState(myState.getSuperState()); |
| |
| // Set this Preference's widget to reflect the restored state |
| mNumberPicker.setValue(myState.value); |
| } |
| </pre> |
| |