web-dev-qa-db-fra.com

Comment utiliser la bibliothèque de support v7 / v14 Preference?

Avec la version M, il existe de nouvelles bibliothèques de support. L’une d’entre elles qui semble très utile est la bibliothèque v7 Preference Support .

Il ne semble pas avoir PreferenceActivity ou quelque chose de similaire, comment l’intégrons-nous dans notre application?

53

Vous devez étendre AppCompatActivity, ce qui est requis pour fragment, et inclure une sous-classe de PreferenceFragmentCompat . Le fragment abstrait nécessite de remplacer une méthode dans laquelle vous devez placer votre logique d’inflation des préférences. Enfin, votre thème d'activité doit spécifier un attribut preferenceTheme.

Lire l'annonce ici . Avec la bibliothèque preference-v7, vous pouvez remplacer PreferenceFragment (API 11+) par PreferenceFragmentCompat sous-classe et SwitchPreference (API 14+) par SwitchPreferenceCompat et que votre écran de paramètres fonctionne depuis l’API 7.

Voici comment je l'ai fait fonctionner:

SettingsActivity.Java

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
    }
}

layout/activity_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent" Android:layout_height="match_parent" >
    <fragment
        Android:name=".SettingsFragment"
        Android:tag=".SettingsFragment"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />
</FrameLayout>

SettingsFragment.Java

public class SettingsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle bundle, String s) {
        addPreferencesFromResource(R.xml.preferences);
    }
}

xml/preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.preference.PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent" Android:layout_height="match_parent">

    <Android.support.v7.preference.PreferenceCategory
        ...>

        <Android.support.v7.preference.ListPreference
            ... />

        <Android.support.v7.preference.SwitchPreferenceCompat
            ... />

        ...

    </Android.support.v7.preference.PreferenceCategory>

    ...

</Android.support.v7.preference.PreferenceScreen>

values ​​/ styles.xml

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
    ...
</style>

thème par défaut de préférence-v7

<style name="PreferenceThemeOverlay">
    <item name="preferenceScreenStyle">@style/Preference.PreferenceScreen</item>
    <item name="preferenceFragmentStyle">@style/PreferenceFragment</item>
    <item name="preferenceCategoryStyle">@style/Preference.Category</item>
    <item name="preferenceStyle">@style/Preference</item>
    <item name="preferenceInformationStyle">@style/Preference.Information</item>
    <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item>
    <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>
    <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item>
    <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item>
    <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
</style>
92
hidro

la réponse d'Hidro est juste, mais une dernière chose à noter:

tilisez simplement des balises XML de préférence telles que PreferenceScreen au lieu du nom complet de la classe. La bibliothèque d'assistance les convertira automatiquement.

Why: Si vous utilisez le nom complet de la classe, la suggestion de code et l'aperçu de la présentation ne fonctionneront pas correctement.

Donc, vous devriez écrire XML comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <PreferenceCategory
        ...>

        <ListPreference
            ... />

        <SwitchPreferenceCompat
            ... />

        ...

    </PreferenceCategory>

    ...

</PreferenceScreen>
12
Junyue Cao

Avec la nouvelle bibliothèque de prise en charge des préférences v7, vous pouvez utiliser le PreferenceFragmentCompat avec n’importe quel Activity ou AppCompatActivity.

public static class PrefsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
}

Vous devez définir preferenceTheme dans votre thème:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  ...
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

De cette façon, vous pouvez personnaliser le preferenceTheme pour styliser les présentations utilisées pour chaque type de préférence sans affecter les autres parties de votre activité.

9
Gabriele Mariotti

J'ai essayé d'implémenter la réponse ci-dessus de Hidro avec une activité qui contenait également une barre d'outils. Cette exception m'a donné une exception d'inflation de présentation à cause de l'erreur suivante:

Causée par: Java.lang.NullPointerException: Tentative d'invoquer la méthode virtuelle 'Android.content.Context Android.support.v4.app.FragmentHostCallback.getContext ()' sur une référence d'objet null

Je n'ai pas été capable de les résoudre, alors j'ai eu recours à ce qui suit:

public class SettingsActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  if(savedInstanceState == null)
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new SettingsFragment()).commit();
  }
}

Avec la disposition suivante pour le SettingsActivity:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
  xmlns:Android="http://schemas.Android.com/apk/res/Android"
  xmlns:tools="http://schemas.Android.com/tools"
  xmlns:app="http://schemas.Android.com/apk/res-auto"
  Android:layout_width="match_parent"
  Android:layout_height="match_parent"
  Android:fitsSystemWindows="true">
  <include layout="@layout/toolbar"/>
  <FrameLayout Android:id="@+id/fragment_container"
               Android:layout_width="match_parent"
               Android:layout_height="match_parent"
               app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</Android.support.design.widget.CoordinatorLayout>

Publié ici car cela pourrait aider si d'autres personnes rencontraient la même exception

0
QuantumTiger

Vous avez raison, il n'existe pas dans appcompat v7, mais Google a en fait ajouté la classe abstraite AppCompatDelegate en tant que délégué que vous pouvez utiliser pour injecter le support de AppCompat dans n'importe quelle activité. Vous pouvez trouver plus de cette réponse .

Voici un exemple d'injection de AppCompatDelegate dans votre activité à partir des échantillons AppCompat de Google. Vous pouvez le trouver ici .

0
Ahmed Hegazy