我正在尝试使用AppCompatActivity和support.v7.preference在子屏幕上实现首选项
根据文档,另一个PreferenceScreen中的每个PreferenceScreen都用作子屏幕,框架将处理单击时显示它. http://developer.android.com/guide/topics/ui/settings.html#Subscreens
... ... ...
这可以使用本机Activity,PreferenceFragment工作正常...但是使用AppCompatActivity和PreferenceFragmentCompat,单击Preference元素只会突出显示它,但不会打开子屏幕.
我在这个文档和代码上找不到任何东西......我需要实现任何额外的回调吗?
编辑:只是为了完整...
这可以工作并打开子屏幕:
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); } } }
编辑:2016年1月25日
在使用support.v7.preference几天后,我总结了我的发现,希望它可以帮助其他人:如何 使用Support.v7.preference与AppCompat和潜在的缺点
它看起来像PreferenceFragmentCompat中的错误或docs的不足.它具有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时会导致另一个问题,
另一种方法是替换此处描述的片段如何从PreferenceFragmentCompat中的Preferences子屏幕移回主屏幕?
这是完整的工作示例,我希望这对某人有帮助.它包括打开首选项子屏幕并返回主设置屏幕.
我在Android开源问题跟踪器中关注了这个问题 - 这里
官方文档缺少加载首选项子屏幕的文档 - 请参阅此处获取官方文档 -
主要高级设置屏幕有2个复选框和一个禁用的子屏幕标题(自定义模式设置): -
检查"自定义"复选框后,将启用子屏幕标题.
单击自定义图案设置后,子屏幕将在新屏幕中打开
以下是带有文档的示例代码: -
在res/xml/preferences.xml文件中: -
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); } }