J'ai une activité qui étend PreferenceActivity . Je charge les préférences à partir du fichier xml . Mais dans certains cas, j'ai besoin de masquer complètement l'une des préférences de l'écran en fonction de l'état de l'application. Il existe une méthode setEnabled, mais ce n'est pas exactement ce que je veux. Je veux supprimer cette préférence de l'écran complètement ... Est-ce possible?
Oui, si vous avez une référence à la fois à la Preference
et à son parent (une PreferenceCategory
ou une PreferenceScreen
)
myPreferenceScreen.removePreference(myPreference);
Si votre Preference
est dans une PreferenceCategory
, vous devez faire ceci:
XML:
<PreferenceCategory
Android:key="category_foo"
Android:title="foo">
<CheckBoxPreference
Android:key="checkPref" />
Java:
CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
mCategory.removePreference(mCheckBoxPref);
Dans le cas où la préférence est un enfant direct de l'écran de préférences, voici un code autonome:
PreferenceScreen screen = getPreferenceScreen();
Preference pref = getPreferenceManager().findPreference("mypreference");
screen.removePreference(pref);
Si vous voulez quelque chose qui modifiera dynamiquement les préférences, par exemple sur un SwitchPreference, j'ai trouvé le meilleur moyen de placer toutes mes sous-options dans des conteneurs de deux catégories. Au départ, vous aurez tout affiché, puis vous supprimerez simplement les bits que vous ne voulez pas. Le plus malin, c’est que vous déclenchez simplement la recréation lorsque quelque chose change, sans avoir à créer manuellement quoi que ce soit, ni à vous soucier de remettre les choses dans le bon ordre.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceCategory prefCatOne= (PreferenceCategory)findPreference("prefCatOne");
PreferenceCategory prefCatTwo= (PreferenceCategory)findPreference("prefCatTwo");
SwitchPreference mySwitchPref= (SwitchPreference)findPreference("mySwitchPref");
PreferenceScreen screen = getPreferenceScreen();
if (mySwitchPref.isChecked()) {
screen.removePreference(prefCatOne);
} else {
screen.removePreference(prefCatTwo);
}
}
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("mySwitchPref")) {
this.recreate();
}
}
Le seul inconvénient que je peux voir avec cela, c'est qu'il y a un flash car l'écran est recréé à partir de zéro.
Dans votre fichier XML:
<PreferenceScreen
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:key="preferenceScreen">
<PreferenceCategory
Android:key="personalisation"
Android:title="your title here">
<ThemedPreference
Android:key="animation" />
</PreferenceScreen>
Dans votre code:
PreferenceScreen pPreferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
PreferenceCategory pCategory = (PreferenceCategory) findPreference("personalisation");
ThemedPreference pThemePref = (ThemedPreference) findPreference("animation");
pPreferenceScreen.removePreference(pCategory); //remove category
pCategory.removePreference(pThemePref); // remove preference
Je recommande d'utiliser la préférence v7, elle a la méthode setVisible()
. Mais je n'ai pas encore essayé. En conséquence, vous devez utiliser PreferenceFragment
au lieu de PreferenceActivity
.
Si vous utilisez PreferenceFragmentCompat vous pouvez définir la visibilité en xml.
Les préférences de votre fichier xml seront automatiquement converties en versions AppCompat. Vous pouvez ensuite utiliser l'attribut 'app: isPreferenceVisible' dans votre fichier xml
preferences.xml
<PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools">
<CheckBoxPreference
Android:defaultValue="false"
Android:key="show.navigation"
Android:title="Show navigation"
app:isPreferenceVisible="false" />
...
L'attribut est documenté à https://developer.Android.com/guide/topics/ui/settings/components-and-attributes
L'ajout de PreferenceFragmentCompat
est documenté à https://developer.Android.com/guide/topics/ui/settings/#inflate_the_hierarchy
Exemple:
public class MySettingsActivity extends AppCompatActivity {
public static class MySettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, new MySettingsFragment())
.commit();
}
}
Dans le fichier XML, vous pouvez créer une préférence masquée en laissant vides les balises title et summary.
<EditTextPreference
Android:defaultValue="toddlerCam"
Android:key="save_photo_dir"
/>
Voici une manière générique de le faire qui fonctionne, que la préférence soit sous PreferenceCategory
ou PreferenceScreen
.
private void removePreference(Preference preference) {
PreferenceGroup parent = getParent(getPreferenceScreen(), preference);
if (parent == null)
throw new RuntimeException("Couldn't find preference");
parent.removePreference(preference);
}
private PreferenceGroup getParent(PreferenceGroup groupToSearchIn, Preference preference) {
for (int i = 0; i < groupToSearchIn.getPreferenceCount(); ++i) {
Preference child = groupToSearchIn.getPreference(i);
if (child == preference)
return groupToSearchIn;
if (child instanceof PreferenceGroup) {
PreferenceGroup childGroup = (PreferenceGroup)child;
PreferenceGroup result = getParent(childGroup, preference);
if (result != null)
return result;
}
}
return null;
}
Depuis l'API Android 26, la méthode getParent()
est disponible: https://developer.Android.com/reference/Android/preference/Preference.html#getParent ()
Bien que vous puissiez faire ce qui suit:
preference.getParent().removePreference(preference);
Si vous souhaitez évaluer et sur la base de ce masque, une alternative peut être
SwitchPreference autenticacionUsuario =
(SwitchPreference) findPreference("key_autenticacion_usuario");
final EditTextPreference Username =
(EditTextPreference) findPreference("key_username_mqtt");
final EditTextPreference Password =
(EditTextPreference) findPreference("key_password_mqtt");
if (!autenticacionUsuario.isChecked()) {
PreferenceCategory preferenceCategory =
(PreferenceCategory) findPreference("category_mqtt");
preferenceCategory.removePreference(Username);
preferenceCategory.removePreference(Password);
}
Tout cela doit être à l'intérieur
public static class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Vous pouvez le faire de deux manières:
1. Si vous utilisez la bibliothèque de support, vous pouvez créer une carte de l’arbre des préférences et de leurs parents, puis supprimer une préférence en utilisant son parent. Voici une fonction pour générer une telle carte:
public static Map<Preference, PreferenceGroup> buildPreferenceParentTree(@NonNull final PreferenceScreen preferenceScreen) {
final Map<Preference, PreferenceGroup> result = new HashMap<>();
final Stack<PreferenceGroup> curParents = new Stack<>();
curParents.add(preferenceScreen);
while (!curParents.isEmpty()) {
final PreferenceGroup parent = curParents.pop();
final int childCount = parent.getPreferenceCount();
for (int i = 0; i < childCount; ++i) {
final Preference child = parent.getPreference(i);
result.put(child, parent);
if (child instanceof PreferenceGroup)
curParents.Push((PreferenceGroup) child);
}
}
return result;
}