我正在尝试使用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>
使用本机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 几天之后,我在这里总结了我的发现,希望它可以帮助其他人: HowTo use support.v7.preference with AppCompat and potential drawbacks
答案 0 :(得分:17)
它看起来像PreferenceFragmentCompat中的错误或文档不足。它有onNavigateToScreen方法,当你点击PreferenceScreen项目时会调用它。
但是方法getCallbackFragment()默认返回null,因此您需要在片段中覆盖它以返回它。您还需要实现PreferenceFragmentCompat.OnPreferenceStartScreenCallback。
<connectionStrings>
<add
name="NorthwindConnectionString"
connectionString="Data Source=serverName;Initial
Catalog=Northwind;Persist Security Info=True;User
ID=userName;Password=password"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
但是当你无法回到初始的PreferenceScreen时会导致另一个问题,
另一种方法是替换此处描述的片段How to move back from Preferences subscreen to main screen in PreferenceFragmentCompat?
答案 1 :(得分:14)
这是完整的工作示例,我希望这对某人有帮助。它包括打开首选项子屏幕并返回主设置屏幕。
我在Android开源问题跟踪器here
中关注了此问题官方文档缺少加载首选项子屏幕的文档 - Refer here for official documentation- -
主要高级设置屏幕有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);
}
}
答案 2 :(得分:2)
你需要记住一个非常重要的事情:
您的首选项屏幕必须包含:
android:key="name_a_unique_key"
否则,它将无法正常工作。我已经花了好几个小时了。
答案 3 :(得分:0)
覆盖 PreferenceFragmentCompat.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'
答案 4 :(得分:0)
似乎Google最终决定在新发布的AndroidX首选项1.1.0-alpha中支持此功能。
This video from Android Dev Summit covers something about preference sub screen.