Alternatives à PreferenceFragment avec android-support-v4

90

Je suis venu à un arrêt soudain dans le développement de mon application car j'ai réalisé que PreferenceFragments n'était pas pris en charge dans cette bibliothèque. Existe-t-il des alternatives qu'un développeur Android débutant peut utiliser pour surmonter cet obstacle?

Ceci est ma fenêtre principale à partir de maintenant

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
<TabHost
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>

                <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            />

</TabHost>
</LinearLayout>

Pour mon TabActivity, j'utilise quelque chose que j'ai trouvé en ligne. Voici un extrait:

public class TabControlActivity extends FragmentActivity implements TabHost.OnTabChangeListener 
{
public static final int INSERT_ID = Menu.FIRST;
public static TabControlActivity thisCtx;
private TabHost mTabHost;
private HashMap mapTabInfo = new HashMap();
private TabInfo mLastTab = null;

private class TabInfo {
     private String tag;
     private Class clss;
     private Bundle args;
     private Fragment fragment;
     TabInfo(String tag, Class clazz, Bundle args) {
         this.tag = tag;
         this.clss = clazz;
         this.args = args;
     }

}

class TabFactory implements TabContentFactory 
{

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }

    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}

...*snip*...

Y a-t-il quelque chose à mettre en œuvre qui ressemble à un fragment de préférence (ou préférenceActivity) à l'aide de la bibliothèque de compatibilité android-support-v4?

CodePrimate
la source
1
duplicata possible de PreferenceFragment a-t
Snicolas
Pas vraiment un doublon car je suis dans une situation où j'ai "besoin" que ces préférences soient affichées dans un tabhost. Voir ma modification
CodePrimate
Voir ma réponse mise à jour . PreferenceFragmentCompata été récemment ajouté à la bibliothèque de support.
theblang

Réponses:

86

MISE À JOUR - 6/11/2015

La bibliothèque Support-v7 comprend désormais PreferenceFragmentCompat. Ce sera donc une meilleure idée de l'utiliser.


Ajoutez le projet suivant en tant que projet de bibliothèque à votre application.

https://github.com/kolavar/android-support-v4-preferencefragment

Vous pouvez tout garder tel quel, y compris votre transaction fragmentée. Lors de l'importation de la PreferenceFragmentclasse, assurez-vous que l'en-tête d'importation correct est user.

import android.support.v4.preference.PreferenceFragment;

au lieu de

import android.preference.PreferenceFragment;
Subin Sebastian
la source
4
Ce code github semble avoir de sérieux problèmes ... Je ne peux pas l'utiliser RingtonePreferenceet OnSharedPreferenceChangeListenerne semble pas non plus avoir de changements!
madlymad
2
Je pensais que c'était une bonne idée d'utiliser cette bibliothèque. Mais j'ai réalisé que ce n'était pas aussi bon que je le pensais. Essayer de remplacer la onPrepareOptionMenuméthode me montre une signature étrange (retourne void) différente de celle par défaut que nous connaissons tous (retourne boolean) !!! un problème grave.
S.Thiongane
9
voté et vous avez droit à un dîner gratuit à chaque fois que vous venez à Madrid ... ce problème me rendait fou!
rupps
7
@mansoulx onPrepareOptionsMenu a toujours un type de retour void sur les fragments (contrairement à Activities, pour lequel il est booléen), donc cette signature est entièrement conforme aux attentes.
Cumbayah
3
Les problèmes avec la bibliothèque devraient probablement être signalés sur le projet github.
Mathijs Segers
128

Je sais que c'est une vieille question, mais vous pouvez maintenant utiliser à PreferenceFragmentCompatpartir decom.android.support:preference-v7:23.3.0

Lucius
la source
4
Bonne trouvaille, c'est l'une des bonnes réponses maintenant.
Mythul
Pour moi, cela ne fonctionne qu'avec com.android.support:preference-v7:23.0.1.
Felipe Mosso
1
Cela ne semble pas être sur les serveurs de dépendance lorsque vous essayez de l'ajouter à partir d'Android Studio. Dois-je ajouter un référentiel pour cela?
Brill Pappin
Il ne contient pas cette classe
JJ Ab
1
J'ai accidentellement voté pour cette réponse et je ne peux pas l'annuler maintenant, alors je vais simplement noter que cela PreferenceFragmentCompata des problèmes majeurs: voir ceci et ce rapport de bogue, par exemple, et bien d'autres ici . J'ai fini par utiliser le obsolète à la PreferenceActivityplace. soupir
Vicky Chijwani
16

Mise à jour importante: la dernière révision du v7 support librarya désormais un PreferenceFragmentCompat natif .

J'utilise cette bibliothèque , qui a un AARin mavenCentralafin que vous puissiez facilement l'inclure si vous utilisez Gradle.

compile 'com.github.machinarius:preferencefragment:0.1.1'

theblang
la source
Pourriez-vous partager comment vous importez et étendez le fragment de support? Merci
Steven
1
@Steve bien sûr! J'ai fait un Gist .
theblang
@mattblang Merci beaucoup!
Steven
@mattblang Merci beaucoup ... Votre aide m'a fait gagner beaucoup de temps
Asad Ullah Rafiq
Exception java.lang.RuntimeException: le contenu a une vue avec l'attribut id 'android.R.id.list' qui n'est pas une classe ListView
Abdul Rahman
10

Vous pouvez utiliser le mien PreferenceFragment.

C'est simple et je n'ai eu aucun problème avec ça jusqu'à présent. Je pense que vous ne pouvez afficher qu'un seul d'entre eux à la fois dans une seule activité, ce qui devrait être OK.

BladeCoder
la source
9

Bibliothèque de prise en charge des préférences: Fragments de préférence pour API 7+, quelle que soit l'activité

Une implémentation simple inclurait un PreferenceFragmentCompat tel que:

public class PreferencesFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.preferences);
    }
}

Vous devrez également définir le thème de préférence dans votre thème:

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

Et ajoutez ceci dans les dépendances: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0
li2
la source
7

Vous pouvez peut-être utiliser une activité réelle et utiliser un fragment, mais je ne pense pas que ce soit un bon choix. Vous devez utiliser PreferenceActivity simple et attendre des améliorations dans les bibliothèques de compatibilité rétro.

Snicolas
la source
1
Je ne peux pas utiliser PreferenceActivity car le reste de mon application se compose d'un onglet. Le fragment de préférence est censé être affiché au-dessus du widget de tabulation. Je devais en faire une activité au lieu de cela, cela prendrait tout l'écran.
CodePrimate
2
Ensuite, utilisez un fragment de liste personnalisé
zapl
2

Vous pouvez utiliser des bibliothèques tierces telles que UnifiedPreferences pour utiliser une seule API pour toutes les versions d'Android.

MarcoDuff
la source
0

Vous pouvez étendre à partir de PreferenceActivity à la place, et si vous souhaitez avoir une ActionBar, vous pouvez l'ajouter en utilisant une Toolbar comme étant au-dessus de la ListView utilisée pour les préférences.

Cela peut être fait en utilisant un LinearLayout vertical qui contient la barre d'outils et un ListView avec android: id = "@ android: id / list" .

Si vous le souhaitez, vous pouvez voir ma solution ici .

développeur android
la source
0

Comme Lucius l'a dit, vous pouvez utiliser PreferenceFragmentCompat :

public class MyPreferenceFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle bundle, String s) {               
            PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
            addPreferencesFromResource(R.xml.preferences);
       }
}

Vous devez inclure sa dépendance dans gradle:

dependencies {
...
    compile 'com.android.support:preference-v7:23.1.X' (wherX = 0,1,...)
...
}

De cette façon, vous pouvez également utiliser FragmentTransaction de android.support.v4.app.FragmentTransaction et PrefernceFragment. Cependant, vous rencontrez peut-être des problèmes avec les thèmes. Si c'est le cas, vous pouvez le résoudre en tenant compte de ce post:

Solution pour faire fonctionner la bibliothèque sur API 7+ tout en conservant le thème matériel sur API 14+

Vicasdia
la source