Alternativen zu PreferenceFragment mit android-support-v4

90

Ich bin bei der Entwicklung meiner App plötzlich zum Stillstand gekommen, als mir klar wurde, dass PreferenceFragments in dieser Bibliothek nicht unterstützt wurden. Gibt es Alternativen, mit denen ein Rookie-Android-Entwickler dieses Hindernis überwinden kann?

Dies ist ab sofort mein Hauptfenster

<?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>

Für meine TabActivity verwende ich etwas, das ich online gefunden habe. Hier ist ein Ausschnitt:

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*...

Gibt es eine Möglichkeit, etwas zu implementieren, das einem Präferenzfragment (oder einer Präferenzaktivität) unter Verwendung der Android-Support-v4-Kompatibilitätsbibliothek ähnelt?

CodePrimate
quelle
Nicht wirklich ein Duplikat, da ich mich in einer Situation befinde, in der ich diese Einstellungen "brauche", um sie in einem Tabhost anzuzeigen. Siehe meine Bearbeitung
CodePrimate
Siehe meine aktualisierte Antwort . PreferenceFragmentCompatwurde kürzlich zur Support-Bibliothek hinzugefügt.
Theblang

Antworten:

86

UPDATE - 6/11/2015

Die Support-v7-Bibliothek enthält jetzt PreferenceFragmentCompat. Es ist also eine bessere Idee, es zu verwenden.


Fügen Sie Ihrer Anwendung das folgende Projekt als Bibliotheksprojekt hinzu.

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

Sie können alles, einschließlich Ihrer Fragmenttransaktion, unverändert lassen. Stellen Sie beim Importieren der PreferenceFragmentKlasse sicher, dass der Benutzer der richtige Importheader ist.

import android.support.v4.preference.PreferenceFragment;

anstatt

import android.preference.PreferenceFragment;
Subin Sebastian
quelle
4
Dieser Github-Code scheint ernsthafte Probleme zu haben ... Ich kann ihn nicht verwenden RingtonePreferenceund OnSharedPreferenceChangeListenerscheint auch keine Änderungen zu bekommen!
Madlymad
2
Ich dachte, dass es eine gute Idee ist, diese Bibliothek zu benutzen. Aber mir wurde klar, dass es nicht so gut ist, wie ich dachte. Der Versuch, die onPrepareOptionMenuMethode zu überschreiben , zeigt mir eine seltsame Signatur (Rückgabe void), die sich von der Standard- Signatur unterscheidet, die wir alle kennen (Rückgabe boolean) !!! ein ernstes Problem.
S.Thiongane
9
upvoted, und Sie haben Anspruch auf ein kostenloses Abendessen, wenn Sie nach Madrid kommen ... dieses Problem hat mich verrückt gemacht!
Rupps
7
@mansoulx onPrepareOptionsMenu hat für Fragmente immer einen ungültigen Rückgabetyp (im Gegensatz zu Aktivitäten, für die es boolesch ist), daher entspricht diese Signatur vollständig den Erwartungen.
Cumbayah
3
Probleme mit der Bibliothek sollten wahrscheinlich im Github-Projekt gemeldet werden.
Mathijs Segers
128

Ich weiß, dass dies eine alte Frage ist, aber Sie können jetzt PreferenceFragmentCompatvon verwendencom.android.support:preference-v7:23.3.0

Lucius
quelle
4
Toller Fund, dies ist jetzt eine der richtigen Antworten.
Mythul
Bei mir funktioniert es nur mit com.android.support:preference-v7:23.0.1.
Felipe Mosso
1
Dies scheint nicht auf den Abhängigkeitsservern zu sein, wenn Sie versuchen, es aus Android Studio hinzuzufügen. Muss ich ein Repository dafür hinzufügen?
Brill Pappin
Es enthält nicht diese Klasse
JJ Ab
1
Ich habe diese Antwort versehentlich positiv bewertet und kann sie jetzt nicht rückgängig machen. Stattdessen stelle ich nur fest, dass PreferenceFragmentCompates einige wichtige Probleme gibt: Sehen Sie sich zum Beispiel diesen und diesen Fehlerbericht und viele weitere hier an . Ich habe stattdessen das veraltete PreferenceActivityverwendet. Seufzer
Vicky Chijwani
16

Wichtiges Update: Die neueste Version von hat v7 support libraryjetzt einen nativen PreferenceFragmentCompat .

Ich verwende diese Bibliothek , die über ein AARIn verfügt, mavenCentralsodass Sie sie bei Bedarf problemlos einbinden können Gradle.

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

theblang
quelle
Können Sie uns mitteilen, wie Sie das Support-Fragment importieren und erweitern? Vielen Dank
Steven
1
@Steve Sicher! Ich habe einen Kern gemacht .
Theblang
@ Mattblang Vielen Dank!
Steven
@ Mattblang Vielen Dank ... Ihre Hilfe spart mir wirklich viel Zeit
Asad Ullah Rafiq
Ausnahme java.lang.RuntimeException: Der Inhalt hat eine Ansicht mit dem ID-Attribut 'android.R.id.list', die keine ListView-Klasse ist
Abdul Rahman
10

Du kannst meine eigene benutzen PreferenceFragment.

Es ist einfach und ich hatte bisher keine Probleme damit. Ich denke, Sie können jeweils nur einen von ihnen in einer einzelnen Aktivität anzeigen, was in Ordnung sein sollte.

BladeCoder
quelle
9

Support-Bibliothek für Einstellungen: Präferenzfragmente für API 7+, unabhängig von der Aktivität

Eine einfache Implementierung würde einen PreferenceFragmentCompat enthalten, wie z.

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

Sie müssen außerdem das PreferenceTheme in Ihrem Thema festlegen:

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

Und fügen Sie dies in Abhängigkeiten hinzu: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0
li2
quelle
7

Sie könnten vielleicht eine echte Aktivität und ein Fragment verwenden, aber ich denke nicht, dass es eine gute Wahl ist. Sie sollten einfache PreferenceActivity verwenden und auf Verbesserungen in Retro-kompatiblen Bibliotheken warten.

Snicolas
quelle
1
Ich kann eine PreferenceActivity nicht verwenden, da der Rest meiner App aus einem Tabwidget besteht. Das Präferenzfragment soll über dem Tabwidget angezeigt werden. Ich sollte es zu einer Aktivität machen, stattdessen würde es den gesamten Bildschirm einnehmen.
CodePrimate
2
Verwenden Sie dann ein benutzerdefiniertes
Listenfragment
0

Sie können von erweitern PreferenceActivity statt und wenn Sie möchten einen ActionBar haben, können Sie es hinzufügen , eine mit Werkzeugleiste über dem Listview als für die Präferenzen verwendet.

Dies kann mithilfe eines vertikalen LinearLayout erfolgen, das die Symbolleiste und eine ListView mit android: id = "@ android: id / list" enthält .

Wenn Sie möchten, können Sie meine Lösung hier sehen .

Android-Entwickler
quelle
0

Wie Lucius sagte, können Sie PreferenceFragmentCompat verwenden :

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

Sie müssen die Abhängigkeit in gradle aufnehmen:

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

Auf diese Weise können Sie auch FragmentTransaction von android.support.v4.app.FragmentTransaction und PrefernceFragment verwenden. Möglicherweise haben Sie jedoch Probleme mit Themen. Wenn dies der Fall ist, können Sie es unter Berücksichtigung dieses Beitrags lösen:

Lösung, mit der die Bibliothek auf API 7+ funktioniert, während das Materialthema auf API 14+ beibehalten wird

Vicasdia
quelle