Ich versuche, Präferenzen mit Unterbildschirmen mit AppCompatActivity und support.v7.preference zu implementieren
Laut den Dokumenten fungiert jedes PreferenceScreen innerhalb eines anderen PreferenceScreen als Unterbildschirm, und das Framework behandelt es, wenn es angeklickt wird . 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>
Dies funktioniert gut, wenn die native Activity, PreferenceFragment ... verwendet wird. Wenn Sie jedoch AppCompatActivity und PreferenceFragmentCompat verwenden, wird durch Klicken auf das Preference-Element nur das Element hervorgehoben, der Unterbildschirm jedoch nicht geöffnet.
Ich konnte nichts finden, wenn ich die Dokumente und den Code las ... muss ich zusätzliche Rückrufe implementieren?
EDIT: Nur zur Vollständigkeit ...
Dies funktioniert und öffnet den Unterbildschirm:
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);
}
}
}
Dies funktioniert nicht/öffnet den Unterbildschirm:
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);
}
}
}
Edit: 25/01/2016
Nachdem ich einige Tage lang mit support.v7.preference getüftelt hatte, habe ich meine Ergebnisse hier zusammengefasst und gehofft, dass dies anderen helfen kann: HowTo, um support.v7.preference mit AppCompat und möglichen Nachteilen zu verwenden
Es sieht aus wie ein Fehler in PreferenceFragmentCompat oder ein Mangel an Dokumenten. Es hat die Methode onNavigateToScreen, die aufgerufen wird, wenn Sie auf das Element PreferenceScreen klicken.
Die Methode getCallbackFragment () gibt jedoch standardmäßig null zurück, daher müssen Sie sie in Ihrem Fragment überschreiben, um dies zurückzugeben. Außerdem müssen Sie PreferenceFragmentCompat.OnPreferenceStartScreenCallback implementieren.
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;
}
}
Es führt jedoch zu einem anderen Problem, wenn Sie nicht zu Ihrem ursprünglichen PreferenceScreen zurückkehren können.
Eine andere Möglichkeit ist, das hier beschriebene Fragment zu ersetzen Wie wechselt man vom Voreinstellungs-Subscreen zum Hauptbildschirm in PreferenceFragmentCompat zurück?
Dies ist ein vollständiges Arbeitsbeispiel. Ich hoffe, dies ist für jemanden hilfreich. Es behandelt das Öffnen des Unterbildschirms für die Einstellungen und das Zurückkehren zum Hauptbildschirm für die Einstellungen.
Ich habe dieses Problem in Android Open Source Issue Tracker -- hier verfolgt
In der offiziellen Dokumentation fehlt die Dokumentation für den Subscreen mit den Ladeeinstellungen -- Informationen zur offiziellen Dokumentation finden Sie hier - -
Der Hauptbildschirm für erweiterte Einstellungen verfügt über 2 Kontrollkästchen und einen deaktivierten Subscreen-Titel (benutzerdefinierte Mustereinstellungen): -
Sobald wir das Kontrollkästchen Benutzerdefiniert aktiviert haben, wird der Titel des Subscreens aktiviert.
Beim Klicken auf Benutzerdefinierte Mustereinstellungen wird der Unterbildschirm in einem neuen Bildschirm geöffnet
Hier ist der Beispielcode mit Dokumentation: -
In der Datei 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 sollte die Schnittstelle PreferenceFragmentCompat.OnPreferenceStartScreenCallback
Implementieren und dann die Methode überschreiben-- 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;
}
Für den Haupteinstellungsbildschirm (Fragment): -
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);
}
}
und zum Schluss für das Laden des Subscreens:
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);
}
}
Eine äußerst wichtige Sache, an die Sie sich erinnern müssen:
Ihr PreferenceScreen muss enthalten:
Android:key="name_a_unique_key"
Sonst funktioniert es nicht. Ich habe Stunden damit verbracht
Überschreiben PreferenceFragmentCompat.OnPreferenceStartScreenCallback
und das Hinzufügen zu meinem Präferenzfragment rettete meinen Tag
@Override
public Fragment getCallbackFragment() {
return this;
}
@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) {
caller.setPreferenceScreen(pref);
return true;
}
Meine Vorzugsversion ist
compile 'com.Android.support:preference-v7:25.0.0'
Es scheint, dass sich Google letztendlich dafür entscheidet, dies in der neu veröffentlichten AndroidX-Einstellung 1.1.0-alpha zu unterstützen.
Dieses Video von Android Dev Summit behandelt etwas über den Voreinstellungs-Unterbildschirm.