Intereting Posts

Подэкран Preference не открывается при использовании support.v7.preference

Я пытаюсь реализовать настройки с субэкранами, используя AppCompatActivity и support.v7.preference

Согласно документам, каждый PreferenceScreen в другом PreferenceScreen функционирует как вспомогательный экран, и структура будет обрабатывать отображение его при нажатии. http://developer.android.com/guide/topics/ui/settings.html#Subscreens

<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> 

Это отлично работает с использованием native Activity, PreferenceFragment … но с помощью AppCompatActivity и PreferenceFragmentCompat щелчок по элементу Preference просто подчеркивает его, но не открывает вспомогательный экран.

Я ничего не смог найти в этом чтении документов и кода … мне нужно реализовать любые дополнительные обратные вызовы?


EDIT: только для полноты …

Это работает и открывает дополнительный экран:

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getFragmentManager().beginTransaction() .replace(android.R.id.content, new DemoPreferenceFragment()) .commit(); } } static public class DemoPreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } } 

Это не работает / открывает дополнительный экран:

 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .replace(android.R.id.content, new DemoPreferenceFragment()) .commit(); } } static public class DemoPreferenceFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle bundle, String s) { addPreferencesFromResource(R.xml.preferences); } } } 

Редактировать: 25/01/2016

После того, как я несколько дней поддерживал поддержку. V7.preference , я подытожил свои выводы здесь, надеясь, что это может помочь другим: HowTo использовать support.v7.preference с AppCompat и потенциальными недостатками

Solutions Collecting From Web of "Подэкран Preference не открывается при использовании support.v7.preference"

Это похоже на ошибку в PreferenceFragmentCompat или недостаточность документов. Он имеет метод onNavigateToScreen, который вызывается, когда вы нажимаете элемент PreferenceScreen.

Но метод getCallbackFragment () возвращает null по умолчанию, поэтому вам нужно переопределить его в своем фрагменте, чтобы вернуть его. Также вам нужно реализовать PreferenceFragmentCompat.OnPreferenceStartScreenCallback.

 public class SettingsFragment extends PreferenceFragmentCompat implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback { public static SettingsFragment newInstance() { return new SettingsFragment(); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.news_settings); } @Override public Fragment getCallbackFragment() { return this; } @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) { preferenceFragmentCompat.setPreferenceScreen(preferenceScreen); return true; } } 

Но это приводит к другой проблеме, когда вы не можете вернуться к исходному экрану PreferenceScreen,

Другой способ – заменить фрагмент, описанный здесь. Как вернуться из основного экрана Preferences на главный экран в PreferenceFragmentCompat?

Это полный рабочий пример, я надеюсь, что это будет полезно для кого-то. Он закрывает окно предпочтений и переходит к главному экрану настроек.

Я следил за этой проблемой в Android-трекере с открытым исходным кодом – здесь

В официальной документации отсутствует документация по загрузке предпочтительного подэкрана – см. Здесь для официальной документации –

Основной экран расширенных настроек как 2 флажка и отключенный заголовок подэкрана (пользовательские настройки шаблона): –

Заголовок подэкрана отключен

Как только мы установим флажок «Пользовательский», заголовок подэкрана будет включен. Заголовок подэкрана включен

При щелчке по настройкам пользовательского шаблона подэкран открывается на новом экране

Введите описание изображения здесь

Вот пример кода с документацией: –

В файле res / xml / preferences.xml: –

  <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:summary="Trying intro text"> <PreferenceCategory android:title="Settings"> <CheckBoxPreference android:defaultValue="true" android:key="defaultPress" android:title="Default settings" /> <CheckBoxPreference android:defaultValue="false" android:key="customKey" android:title="Custom" /> <PreferenceScreen android:key="customPrefKey" android:title="Custom Pattern Settings"> <PreferenceCategory android:key="customSettingsKey" android:title="Custom Settings"> <ListPreference android:defaultValue="4" android:entries="@array/initialClickArray" android:entryValues="@array/initialClickValues" android:key="initialClicks" android:summary="initialClicksSummary" android:title="No. Of Clicks" /> <ListPreference android:defaultValue="5" android:entries="@array/initialTimeArray" android:entryValues="@array/initialTimeValues" android:key="initialTimeKey" android:summary="Time to complete clicks" android:title="Time to complete" /> </PreferenceCategory> </PreferenceScreen> </PreferenceCategory> </PreferenceScreen> 

MainActivity.java должен реализовать интерфейс PreferenceFragmentCompat.OnPreferenceStartScreenCallback а затем переопределить метод – onPreferenceStartScreen

 public class MainActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback { private static final String TAG = MainActivity.class.getName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment = null; if (savedInstanceState == null) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragment = new AdvancedSettingsFragment().newInstance("Advanced Setting"); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit(); } } @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) { Log.d(TAG, "callback called to attach the preference sub screen"); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); AdvancedSettingsSubScreenFragment fragment = AdvancedSettingsSubScreenFragment.newInstance("Advanced Settings Subscreen"); Bundle args = new Bundle(); //Defining the sub screen as new root for the subscreen args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey()); fragment.setArguments(args); ft.replace(R.id.fragment_container, fragment, preferenceScreen.getKey()); ft.addToBackStack(null); ft.commit(); return true; } 

Для главного экрана настроек (фрагмент): –

 public class AdvancedSettingsFragment extends PreferenceFragmentCompat { private static final String TAG = AdvancedSettingsFragment.class.getName(); public static final String PAGE_ID = "page_id"; public static AdvancedSettingsFragment newInstance(String pageId) { AdvancedSettingsFragment f = new AdvancedSettingsFragment(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return (f); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); final CheckBoxPreference customPreference = (CheckBoxPreference) findPreference("customKey"); final Preference customSettings = (Preference) findPreference("customPrefKey"); // First time loading the preference screen, we check the saved settings and enable/disable the custom settings, based on the custom check box //get the customSettings value from shared preferences if (getCustomSettings(getActivity())) { customPreference.setChecked(true); customSettings.setEnabled(true); } else { customPreference.setChecked(false); customSettings.setEnabled(false); } customPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object selectedValue) { Log.d(TAG, "Inside on preference change of custom checkbox selection " + selectedValue.getClass()); if ((Boolean) selectedValue) { customSettings.setEnabled(true); }else{ customSettings.setEnabled(false); } return true; } }); } private boolean getCustomSettings(Context context) { return PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("customKey", false); } } 

И, наконец, для загрузки подэкрана:

 public class AdvancedSettingsSubScreenFragment extends PreferenceFragmentCompat { private static final String TAG = AdvancedSettingsSubScreenFragment.class.getName(); public static final String PAGE_ID = "page_id"; public static AdvancedSettingsSubScreenFragment newInstance(String pageId) { AdvancedSettingsSubScreenFragment f = new AdvancedSettingsSubScreenFragment(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return (f); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // rootKey is the name of preference sub screen key name , here--customPrefKey setPreferencesFromResource(R.xml.preferences, rootKey); Log.d(TAG, "onCreatePreferences of the sub screen " + rootKey); } } 

Одна чрезвычайно важная вещь, которую вам нужно запомнить:

Экран PreferenceScreen должен содержать:

 android:key="name_a_unique_key" 

В противном случае это не сработает. Я провел несколько часов с

Переопределение предпочтенияFragmentCompat.OnPreferenceStartScreenCallback

И добавив следующее к моему фрагменту предпочтения, сохраненному моим днем

 @Override public Fragment getCallbackFragment() { return this; } @Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) { caller.setPreferenceScreen(pref); return true; } 

Моя предпочтительная версия

 compile 'com.android.support:preference-v7:25.0.0'