启用后新的 PreferenceScreen 打不开
New PreferenceScreen doesn't open after enabling
我一直在为我的项目使用 AndroidX Preference 库。该项目有主菜单和子菜单。我已经设置了主菜单中的 CheckBoxPreference 和子菜单中的 PreferenceScreen 之间的依赖关系。 CheckBox 被选中时,PreferenceScreen 被启用,但我无法打开子菜单。
如果我删除依赖项,一切正常!
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="checkbox1"
android:summaryOff="Description of checkbox 1 off"
android:summaryOn="Description of checkbox 1 on"
android:title="CheckBox 1">
</CheckBoxPreference>
<ListPreference
android:dependency="checkbox1"
android:entries="@array/entries"
android:entryValues="@array/entry_values"
android:key="list"
android:summary="Description of list"
android:title="List">
</ListPreference>
<CheckBoxPreference
android:key="checkbox2"
android:summary="Description of checkbox 2"
android:title="CheckBox 2">
</CheckBoxPreference>
<PreferenceScreen
android:key="screen"
android:dependency="checkbox2"
android:summary="Description of screen"
android:title="Screen">
<CheckBoxPreference
android:key="checkbox3"
android:summary="Description of checkbox 3"
android:title="CheckBox 3">
</CheckBoxPreference>
<PreferenceCategory
android:key="category1"
android:summary="Description of category 1"
android:title="Category 1">
<CheckBoxPreference
android:key="checkbox4"
android:summary="Description of checkbox 4"
android:title="CheckBox 4">
</CheckBoxPreference>
</PreferenceCategory>
<PreferenceCategory
android:key="category2"
android:dependency="checkbox3"
android:summary="Description of category 2"
android:title="Category 2">
<CheckBoxPreference
android:key="chb5"
android:summary="Description of checkbox 5"
android:title="CheckBox 5">
</CheckBoxPreference>
<CheckBoxPreference
android:key="chb6"
android:summary="Description of checkbox 6"
android:title="CheckBox 6">
</CheckBoxPreference>
</PreferenceCategory>
</PreferenceScreen>
</androidx.preference.PreferenceScreen>
PreferencesFragment.java
public class PreferencesFragment extends PreferenceFragmentCompat {
CheckBoxPreference checkBoxPreference;
PreferenceCategory preferenceCategory;
public static final String FRAGMENT_TAG = "my_preference_fragment";
public PreferencesFragment(){
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
checkBoxPreference = findPreference("checkbox3");
preferenceCategory = findPreference("category2");
preferenceCategory.setEnabled(checkBoxPreference.isChecked());
checkBoxPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
preferenceCategory.setEnabled(checkBoxPreference.isChecked());
return false;
}
});
}
}
PreferencesActivity.java
public class PreferencesActivity extends AppCompatActivity
implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(PreferencesFragment.FRAGMENT_TAG);
if (fragment == null) {
fragment = new PreferencesFragment();
}
}
getSupportFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new PreferencesFragment())
.commit();
}
@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller,
PreferenceScreen preferenceScreen) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
PreferencesFragment preferencesFragment = new PreferencesFragment();
Bundle args = new Bundle();
args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey());
preferencesFragment.setArguments(args);
fragmentTransaction.replace(android.R.id.content, preferencesFragment,
preferenceScreen.getKey());
fragmentTransaction.addToBackStack(preferenceScreen.getKey());
fragmentTransaction.commit();
return true;
}
}
我希望开始一个新的偏好,但实际上我得到了这个:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: edu.allexfiloenko.lesson62_preferences_enable, PID: 9233
java.lang.IllegalStateException: Dependency "checkbox2" not found for preference "screen" (title: "Screen"
at androidx.preference.Preference.registerDependency(Preference.java:1393)
at androidx.preference.Preference.onAttached(Preference.java:1357)
at androidx.preference.PreferenceGroup.onAttached(PreferenceGroup.java:444)
at androidx.preference.PreferenceFragmentCompat.bindPreferences(PreferenceFragmentCompat.java:484)
at androidx.preference.PreferenceFragmentCompat.onViewCreated(PreferenceFragmentCompat.java:272)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:892)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2076)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1821)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
这实际上不是受支持的用例,一般不再建议嵌套 PreferenceScreen。
相反,我会推荐一个单独的片段,具有单独的层次结构。您可以在第一个屏幕中使用首选项,以 link 进入第二个屏幕。那么这个 Preference 就会有依赖,这应该可以正常工作。
为了兴趣,我认为这里的实际问题是,当你移动到新屏幕后,外部层次结构不再存在,但是作为新根的 PreferenceScreen 仍然有这个依赖,所以它寻找不再存在的偏好 "checkbox2" :)
有关详细信息,请参阅 Settings guide。
我一直在为我的项目使用 AndroidX Preference 库。该项目有主菜单和子菜单。我已经设置了主菜单中的 CheckBoxPreference 和子菜单中的 PreferenceScreen 之间的依赖关系。 CheckBox 被选中时,PreferenceScreen 被启用,但我无法打开子菜单。
如果我删除依赖项,一切正常!
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="checkbox1"
android:summaryOff="Description of checkbox 1 off"
android:summaryOn="Description of checkbox 1 on"
android:title="CheckBox 1">
</CheckBoxPreference>
<ListPreference
android:dependency="checkbox1"
android:entries="@array/entries"
android:entryValues="@array/entry_values"
android:key="list"
android:summary="Description of list"
android:title="List">
</ListPreference>
<CheckBoxPreference
android:key="checkbox2"
android:summary="Description of checkbox 2"
android:title="CheckBox 2">
</CheckBoxPreference>
<PreferenceScreen
android:key="screen"
android:dependency="checkbox2"
android:summary="Description of screen"
android:title="Screen">
<CheckBoxPreference
android:key="checkbox3"
android:summary="Description of checkbox 3"
android:title="CheckBox 3">
</CheckBoxPreference>
<PreferenceCategory
android:key="category1"
android:summary="Description of category 1"
android:title="Category 1">
<CheckBoxPreference
android:key="checkbox4"
android:summary="Description of checkbox 4"
android:title="CheckBox 4">
</CheckBoxPreference>
</PreferenceCategory>
<PreferenceCategory
android:key="category2"
android:dependency="checkbox3"
android:summary="Description of category 2"
android:title="Category 2">
<CheckBoxPreference
android:key="chb5"
android:summary="Description of checkbox 5"
android:title="CheckBox 5">
</CheckBoxPreference>
<CheckBoxPreference
android:key="chb6"
android:summary="Description of checkbox 6"
android:title="CheckBox 6">
</CheckBoxPreference>
</PreferenceCategory>
</PreferenceScreen>
</androidx.preference.PreferenceScreen>
PreferencesFragment.java
public class PreferencesFragment extends PreferenceFragmentCompat {
CheckBoxPreference checkBoxPreference;
PreferenceCategory preferenceCategory;
public static final String FRAGMENT_TAG = "my_preference_fragment";
public PreferencesFragment(){
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
checkBoxPreference = findPreference("checkbox3");
preferenceCategory = findPreference("category2");
preferenceCategory.setEnabled(checkBoxPreference.isChecked());
checkBoxPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
preferenceCategory.setEnabled(checkBoxPreference.isChecked());
return false;
}
});
}
}
PreferencesActivity.java
public class PreferencesActivity extends AppCompatActivity
implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Fragment fragment = getSupportFragmentManager()
.findFragmentByTag(PreferencesFragment.FRAGMENT_TAG);
if (fragment == null) {
fragment = new PreferencesFragment();
}
}
getSupportFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new PreferencesFragment())
.commit();
}
@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller,
PreferenceScreen preferenceScreen) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
PreferencesFragment preferencesFragment = new PreferencesFragment();
Bundle args = new Bundle();
args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey());
preferencesFragment.setArguments(args);
fragmentTransaction.replace(android.R.id.content, preferencesFragment,
preferenceScreen.getKey());
fragmentTransaction.addToBackStack(preferenceScreen.getKey());
fragmentTransaction.commit();
return true;
}
}
我希望开始一个新的偏好,但实际上我得到了这个:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: edu.allexfiloenko.lesson62_preferences_enable, PID: 9233
java.lang.IllegalStateException: Dependency "checkbox2" not found for preference "screen" (title: "Screen"
at androidx.preference.Preference.registerDependency(Preference.java:1393)
at androidx.preference.Preference.onAttached(Preference.java:1357)
at androidx.preference.PreferenceGroup.onAttached(PreferenceGroup.java:444)
at androidx.preference.PreferenceFragmentCompat.bindPreferences(PreferenceFragmentCompat.java:484)
at androidx.preference.PreferenceFragmentCompat.onViewCreated(PreferenceFragmentCompat.java:272)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:892)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2076)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1821)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
这实际上不是受支持的用例,一般不再建议嵌套 PreferenceScreen。
相反,我会推荐一个单独的片段,具有单独的层次结构。您可以在第一个屏幕中使用首选项,以 link 进入第二个屏幕。那么这个 Preference 就会有依赖,这应该可以正常工作。
为了兴趣,我认为这里的实际问题是,当你移动到新屏幕后,外部层次结构不再存在,但是作为新根的 PreferenceScreen 仍然有这个依赖,所以它寻找不再存在的偏好 "checkbox2" :)
有关详细信息,请参阅 Settings guide。