Alternatywy dla PreferenceFragment z android-support-v4


90

Nagle zatrzymałem się w rozwoju mojej aplikacji, gdy zdałem sobie sprawę, że PreferenceFragments nie są obsługiwane w tej bibliotece. Czy są jakieś alternatywy, z których początkujący programista Android może skorzystać, aby pokonać tę przeszkodę?

To jest teraz moje główne okno

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

Do mojego TabActivity używam czegoś, co znalazłem online. Oto fragment:

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

Czy jest coś do zaimplementowania czegoś, co przypomina preferencefragment (lub preferenceActivity) przy użyciu biblioteki zgodności android-support-v4?



Właściwie nie jest to duplikat, ponieważ jestem w sytuacji, w której „potrzebuję”, aby te preferencje były wyświetlane w ramach tabhosta. Zobacz moją edycję
CodePrimate

Zobacz moją zaktualizowaną odpowiedź . PreferenceFragmentCompatzostał niedawno dodany do biblioteki wsparcia.
theblang

Odpowiedzi:


86

AKTUALIZACJA - 11.06.2015

Biblioteka Support-v7 zawiera teraz PreferenceFragmentCompat. Więc lepiej będzie z niego skorzystać.


Dodaj następujący projekt jako projekt biblioteki do swojej aplikacji.

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

Możesz zachować wszystko, w tym transakcję fragmentową, tak jak jest. Podczas importowania PreferenceFragmentklasy upewnij się, że prawidłowy nagłówek importu to user.

import android.support.v4.preference.PreferenceFragment;

zamiast

import android.preference.PreferenceFragment;

4
Ten kod github wydaje się mieć poważne problemy ... Nie mogę używać, RingtonePreferencea także OnSharedPreferenceChangeListenernie wydaje się, żebym wprowadzał żadnych zmian!
Mando Stam

2
Pomyślałem, że warto skorzystać z tej biblioteki. Ale zdałem sobie sprawę, że to nie jest tak dobre, jak myślałem. Próba zastąpienia onPrepareOptionMenumetody pokazuje mi dziwny podpis (zwraca void) inny niż domyślny, który wszyscy znamy (zwraca boolean) !!! poważny problem.
S.Thiongane,

9
Za każdym razem, gdy przyjeżdżasz do Madrytu, masz prawo do darmowej kolacji ... ten problem doprowadzał mnie do szału!
rupps

7
@mansoulx onPrepareOptionsMenu zawsze ma zwrotny typ void dla fragmentów (w przeciwieństwie do działań, dla których jest to wartość logiczna), więc ten podpis jest całkowicie zgodny z oczekiwaniami.
Cumbayah

3
Problemy z biblioteką powinny być prawdopodobnie zgłaszane w projekcie github.
Mathijs Segers,

128

Wiem, że to stare pytanie, ale możesz teraz użyć PreferenceFragmentCompatzcom.android.support:preference-v7:23.3.0


4
Świetne znalezisko, to jest teraz jedna z poprawnych odpowiedzi.
Mythul

U mnie działa tylko z com.android.support:preference-v7:23.0.1.
Felipe Mosso

1
Wydaje się, że nie ma tego na serwerach zależności podczas próby dodania go z Android Studio. CZY muszę dodać do tego repozytorium?
Brill Pappin

Nie zawiera tej klasy
JJ Ab

1
Przypadkowo zagłosowałem za tą odpowiedzią i nie mogę tego teraz cofnąć, więc zamiast tego po prostu zauważę, że PreferenceFragmentCompatma kilka poważnych problemów: zobacz na przykład ten i ten raport o błędzie, a także wiele innych tutaj . Skończyło się na tym, że PreferenceActivityzamiast tego użyłem wycofanego . westchnienie
Vicky Chijwani

16

Ważna aktualizacja: najnowsza wersja z v7 support libraryobecnie posiada natywną PreferenceFragmentCompat .

Używam tej biblioteki , która ma AARin, mavenCentralwięc możesz ją łatwo dołączyć, jeśli używasz Gradle.

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


Czy mógłbyś podzielić się tym, jak importujesz i rozszerzasz fragment wsparcia? Dzięki
Steven,

1
@Steve Sure! Zrobiłem Gist .
theblang

@mattblang Wielkie dzięki!
Steven,

@mattblang Wielkie dzięki ... Twoja pomoc naprawdę oszczędza mój czas
Asad Ullah Rafiq

Wyjątek java.lang.RuntimeException: Treść ma widok z atrybutem id „android.R.id.list”, który nie jest klasą ListView
Abdul Rahman

10

Możesz użyć mojego własnego PreferenceFragment.

To proste i do tej pory nie miałem z tym żadnych problemów. Myślę, że możesz wyświetlić tylko jeden z nich naraz w jednym działaniu, co powinno być OK.


9

Biblioteka obsługi preferencji: fragmenty preferencji dla API 7+, bez względu na aktywność

Prosta implementacja obejmowałaby PreferenceFragmentCompat, na przykład:

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

Musisz także ustawić preferenceTheme w swoim motywie:

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

I dodaj to w zależnościach: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0

7

Możesz użyć prawdziwej aktywności i fragmentu, ale nie sądzę, że to dobry wybór. Powinieneś użyć prostego PreferenceActivity i poczekać na ulepszenia w bibliotekach kompatybilnych z retro.


1
Nie mogę użyć PreferenceActivity, ponieważ reszta mojej aplikacji składa się z tabwidżetu. Fragment preferencji powinien być wyświetlany nad widgetem tabulacji. Miałem to zrobić, zamiast tego zajmowałoby cały ekran.
CodePrimate,

2
Następnie użyj fragmentu listy niestandardowej
zapl


0

Zamiast tego możesz rozszerzyć z PreferenceActivity , a jeśli chcesz mieć ActionBar, możesz dodać go za pomocą paska narzędzi jako znajdującego się powyżej ListView używanego dla preferencji.

Można to zrobić za pomocą pionowego LinearLayout, który zawiera pasek narzędzi i ListView z android: id = "@ android: id / list" .

Jeśli chcesz, możesz zobaczyć moje rozwiązanie tutaj .


0

Jak powiedział Lucjusz, możesz użyć 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);
       }
}

Musisz uwzględnić jego zależność w gradle:

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

W ten sposób możesz również użyć FragmentTransaction z android.support.v4.app.FragmentTransaction i PrefernceFragment. Jednak możesz mieć problemy z motywami. Jeśli tak, możesz go rozwiązać, biorąc pod uwagę ten post:

Rozwiązanie sprawiające, że biblioteka działa na API 7+, zachowując motyw materiału na API 14+

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.