Miałem problem z używaniem nowego paska narzędzi Material Design w bibliotece pomocy na ekranie Preferencje.
Mam plik settings.xml jak poniżej:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/AddingItems"
android:key="pref_key_storage_settings">
<ListPreference
android:key="pref_key_new_items"
android:title="@string/LocationOfNewItems"
android:summary="@string/LocationOfNewItemsSummary"
android:entries="@array/new_items_entry"
android:entryValues="@array/new_item_entry_value"
android:defaultValue="1"/>
</PreferenceCategory>
</PreferenceScreen>
Ciągi są zdefiniowane w innym miejscu.
android
android-actionbar
android-5.0-lollipop
android-actionbar-compat
android-toolbar
James Cross
źródło
źródło
Odpowiedzi:
Znajdź repozytorium GitHub: tutaj
Trochę późno na imprezę, ale to jest moje rozwiązanie, którego używam jako obejścia, aby nadal używać
PreferenceActivity
:settings_toolbar.xml :
SettingsActivity.java :
Result :
UPDATE (zgodność z piernikami):
Zgodnie z komentarzami urządzenia Gingerbread zwracają wyjątek NullPointerException w tej linii:
NAPRAWIĆ:
SettingsActivity.java :
Wszelkie problemy z powyższym daj mi znać!
AKTUALIZACJA 2: OBEJŚCIE BARWIENIA
Jak wskazano w wielu notatkach deweloperskich,
PreferenceActivity
nie obsługuje barwienia elementów, jednak używając kilku wewnętrznych klas MOŻESZ to osiągnąć. Dzieje się tak do momentu usunięcia tych klas. (Działa przy użyciu appCompat support-v7 v21.0.3).Dodaj następujące importy:
Następnie nadpisz
onCreateView
metodę:Result:
AppCompat 22.1
AppCompat 22.1 wprowadził nowe przyciemniane elementy, co oznacza, że nie ma już potrzeby wykorzystywania klas wewnętrznych, aby osiągnąć ten sam efekt, co podczas ostatniej aktualizacji. Zamiast tego postępuj zgodnie z tym (nadal nadrzędnym
onCreateView
):EKRANY PREFERENCYJNE ZAGNIEŻDŻONE
Wiele osób ma problemy z włączaniem paska narzędzi do zagnieżdżonego,
<PreferenceScreen />
jednak znalazłem rozwiązanie! - Po wielu próbach i błędach!Dodaj do swojego
SettingsActivity
:Powodem tego
PreferenceScreen
jest to, że są one oparte na oknach opakowujących, więc musimy uchwycić układ okna dialogowego, aby dodać do niego pasek narzędzi.Cień paska narzędzi
Zgodnie z projektem importowanie
Toolbar
nie pozwala na elewację i cieniowanie w urządzeniach starszych niż 21, więc jeśli chcesz mieć elewację na swoimToolbar
, musisz owinąć ją wAppBarLayout
:settings_toolbar.xml
:Nie zapominając o dodaniu biblioteki obsługi projektowania jako zależności w
build.gradle
pliku:Android 6.0
Zbadałem zgłoszony problem nakładania się i nie mogę go odtworzyć.
Pełny kod używany jak powyżej daje następujące wyniki:
Jeśli czegoś brakuje, daj mi znać za pośrednictwem tego repozytorium, a zbadam sprawę.
źródło
Możesz użyć
PreferenceFragment
, jako alternatywy dlaPreferenceActivity
. OtoActivity
przykład pakowania :A oto plik układu (pref_with_actionbar):
I na koniec
PreferenceFragment
:Mam nadzieję, że to komuś pomoże.
źródło
ActionBarActivity
do uzyskania paska narzędzi i powiązanych funkcji, nie będzieonBuildHeaders()
możliwości zastąpienia ani faktycznej obsługi preferencji w działaniu. Jeśli używasz staregoPreferenceActivity
, nie masz paska narzędzi i powiązanych funkcji (tak, możesz miećToolbar
układ i, ale nie możesz wywołaćsetSupportActionBar()
. Tak więc, z nagłówkami preferencji lub zagnieżdżonymi ekranami preferencji, wydaje się, że utknęliśmy.Całkowicie nowa aktualizacja.
Po pewnych eksperymentach wydaje mi się, że znalazłem działające rozwiązanie AppCompat 22.1+ dla zagnieżdżonych ekranów preferencji.
Po pierwsze, jak wspomniano w wielu odpowiedziach (w tym w jednej tutaj), musisz użyć nowego
AppCompatDelegate
. Skorzystaj zAppCompatPreferenceActivity.java
pliku z demonstracji pomocy ( https://android.googlesource.com/platform/development/+/58bf5b99e6132332afb8b44b4c8cedf5756ad464/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompivityatPreva ) z niego lub skopiuj odpowiednie funkcje do własnychPreferenceActivity
. Tutaj pokażę pierwsze podejście:Towarzyszący układ jest raczej prosty i zwykły (
layout/settings_page.xml
):Same preferencje są zdefiniowane jak zwykle (
xml/settings.xml
):Do tego momentu nie ma żadnej różnicy w stosunku do rozwiązań w sieci. Właściwie możesz tego użyć, nawet jeśli nie masz zagnieżdżonych ekranów, żadnych nagłówków, tylko jeden ekran.
Używamy wspólnego
PreferenceFragment
dla wszystkich głębszych stron, różniących sięextra
parametrami w nagłówkach. Każda strona będzie miała oddzielny XML ze wspólnymPreferenceScreen
wnętrzem (xml/settings_page1.xml
i in.). Fragment używa tego samego układu co ćwiczenie, łącznie z paskiem narzędzi.Na koniec krótkie podsumowanie tego, jak to faktycznie działa. Nowa
AppCompatDelegate
pozwala nam korzystać z dowolnej aktywności z funkcjami AppCompat, nie tylko z tych, które wykraczają poza działania faktycznie w AppCompat. Oznacza to, że możemy zamienić stare dobrePreferenceActivity
w nowe i jak zwykle dodać pasek narzędzi. Od tego momentu możemy trzymać się starych rozwiązań dotyczących ekranów preferencji i nagłówków, bez odstępstwa od istniejącej dokumentacji. Jest tylko jedna ważna kwestia: nie używajonCreate()
w ćwiczeniu, ponieważ doprowadzi to do błędów. Posługiwać sięonBuildHeaders()
do wszystkich operacji, takich jak dodawanie paska narzędzi.Jedyną prawdziwą różnicą jest to, że to właśnie sprawia, że działa z zagnieżdżonymi ekranami, ponieważ możesz zastosować to samo podejście do fragmentów. Możesz użyć ich w
onCreateView()
ten sam sposób, nadmuchując własny układ zamiast systemowego, dodając pasek narzędzi w taki sam sposób jak w ćwiczeniu.źródło
R.drawable.abc_ic_ab_back_mtrl_am_alpha
PreferenceFragmentCompat
zamiastPreferenceFragment
. Skonfigurowaniepreference-header
z,xmlns:app="http://schemas.android.com/apk/res-auto"
a następnieapp:fragment
zamiastandroid:fragment
nie ładuje żadnego nowego ekranu ustawień wstępnych. Więc masz problemy z kompatybilnością wsteczną ... sugestiami?Jeśli chcesz użyć PreferenceHeaders, możesz użyć następującego podejścia:
layout / activity_settings.xml
Możesz tutaj użyć dowolnego układu, po prostu upewnij się, że dostosowałeś go również w kodzie Java.
I na koniec twój plik z nagłówkami (xml / pref_headers.xml)
źródło
android.R.id.content
, biorąc pod uwagę, że zamiast tego przekazywaliśmy zListView
zandroid.R.id.list
dla samej listy preferencji (i nadal robimy, jeśli używamy metody bez fragmentów, bez nagłówka).Wraz z wydaniem biblioteki obsługi systemu Android 22.1.0 i nowej AppCompatDelegate, tutaj można znaleźć ładną próbkę implementacji PreferenceActivity z obsługą materiałów z kompatybilnością wsteczną.
Aktualizacja Działa również na zagnieżdżonych ekranach.
https://android.googlesource.com/platform/development/+/marshmallow-mr3-release/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatPreferenceActivity.java
źródło
Chociaż powyższe odpowiedzi wydają się skomplikowane, jeśli chcesz szybko naprawić rozwiązanie, aby korzystać z paska narzędzi Toolbar z obsługą API 7 i jednocześnie rozszerzać
PreferenceActivity
, otrzymałem pomoc z tego projektu poniżej.https://github.com/AndroidDeveloperLB/ActionBarPreferenceActivity
activity_settings.xml
SettingsActivity.java
źródło
Ja też szukaliśmy rozwiązania dodając v7 pasek oporowy ( API 25 ) do AppCompatPreferenceActivity (który jest automatycznie utworzony przez AndroidStudio podczas dodawania SettingsActivity). Po przeczytaniu kilku rozwiązań i wypróbowaniu każdego z nich, starałem się wyświetlić wygenerowane przykłady PreferenceFragment również z paskiem narzędzi.
Zmodyfikowane rozwiązanie, które się sprawdziło, pochodziło z „ Gabora ”.
Jednym z zastrzeżeń, z jakimi się spotkałem, były pożary „onBuildHeaders” tylko raz. Jeśli obrócisz urządzenie (takie jak telefon) na bok, widok zostanie odtworzony, a PreferenceActivity pozostanie ponownie bez paska narzędzi, jednak PreferenceFragments zachowa swoje.
Próbowałem użyć „onPostCreate”, aby wywołać „setContentView”, podczas gdy to działało w celu odtworzenia paska narzędzi po zmianie orientacji, PreferenceFragments był wtedy renderowany jako pusty.
To, co wymyśliłem, wykorzystuje prawie każdą wskazówkę i odpowiedź, jaką mogłem przeczytać na ten temat. Mam nadzieję, że inni też uznają to za przydatne.
Zaczniemy od Java
Najpierw w (wygenerowanym) AppCompatPreferenceActivity.java zmodyfikowałem 'setSupportActionBar' w następujący sposób:
Po drugie , utworzyłem nową klasę o nazwie AppCompatPreferenceFragment.java (jest to aktualna nieużywana nazwa, chociaż może tak nie pozostać!):
To jest część odpowiedzi Gabora, która zadziałała.
Ostatnio , aby uzyskać konsystencję musimy dokonać pewnych zmian SettingsActivity.java :
Część kodu została pominięta ze względu na zwięzłość. Kluczowe składniki tutaj to „ onAttachedFragment ”, „ onPostCreate ”, a „GeneralPreferenceFragment” rozszerza teraz niestandardowy „ AppCompatPreferenceFragment ” zamiast PreferenceFragment.
Podsumowanie kodu : Jeśli fragment jest obecny, fragment wstrzykuje nowy układ i wywołuje zmodyfikowaną funkcję setSupportActionBar. Jeśli fragmentu nie ma, SettingsActivity wstrzykuje nowy układ w „onPostCreate”
Teraz przejdźmy do XML (bardzo proste):
activity_settings.xml :
app_bar_settings.xml :
content_settings.xml :
Wynik końcowy :
źródło
Mam nowe (prawdopodobnie schludniejsze) rozwiązanie, które wykorzystuje
AppCompatPreferenceActivity
próbki z Support v7. Mając ten kod w ręku, stworzyłem własny układ zawierający pasek narzędzi:Następnie w moim
AppCompatPreferenceActivity
zmieniłem,setContentView
aby utworzyć nowy układ i umieściłem dostarczony układ w moimFrameLayout
:Następnie po prostu przedłużam
AppCompatPreferenceActivity
, pozwalając mi na wywoływaniesetSupportActionBar((Toolbar) findViewById(R.id.toolbar))
i zawyżanie elementów menu na pasku narzędzi. Wszystko to przy zachowaniu zalet plikuPreferenceActivity
.źródło
Zachowajmy tutaj prostotę i przejrzystość, bez naruszania żadnego wbudowanego układu
źródło
root.getChildAt(0);
wracanull
.Podczas pracy nad tym znalazłem to proste rozwiązanie. Najpierw musimy stworzyć układ dla czynności związanych z ustawieniami.
activity_settings.xml
Upewnij się, że dodajesz widok listy z
android:id="@android:id/list"
, w przeciwnym razie zostanie rzuconyNullPointerException
Następnym krokiem jest dodanie
onCreate
metody (Zastąp) w aktywności ustawieńSettings.java
Upewnij się, że importujesz
android.suppoer.v7.widget.Toolbar
. Powinno to działać prawie we wszystkich interfejsach API powyżej 16 (Jelly Bean i nowszych)źródło
Chciałbym kontynuować zaznaczone rozwiązanie Jamesa Crossa, ponieważ po tym pojawia się problem z zamykaniem tylko aktywnego zagnieżdżonego ekranu (PreferenceFragment), aby nie zamykać również SettingsActivity.
Właściwie to działa na wszystkich zagnieżdżonych ekranach (więc nie rozumiem rozwiązania Gábor, które wypróbowałem bez powodzenia, działa do pewnego momentu, ale jest to bałagan wielu pasków narzędzi), ponieważ kiedy użytkownik kliknie ekran preferencji podrzędnych , tylko fragment jest zmieniany (patrz
<FrameLayout android:id="@+id/content_frame" .../>
) nie pasek narzędzi, który pozostaje zawsze aktywny i widoczny, ale należy zaimplementować niestandardowe zachowanie, aby odpowiednio zamknąć każdy fragment.W klasie głównej,
SettingsActivity
która rozszerzaActionBarActivity
, należy zaimplementować następujące metody. Zauważ, że prywatnysetupActionBar()
jest wywoływany zonCreate()
Aby uzyskać tytuł wybranego zagnieżdżonego ekranu, powinieneś pobrać odniesienie do swojego paska narzędzi i ustawić odpowiedni tytuł za pomocą
toolbar.setTitle(R.string.pref_title_general);
(na przykład).Nie ma potrzeby wdrażania
getSupportActionBar()
we wszystkich PreferenceFragment, ponieważ przy każdym zatwierdzeniu zmienia się tylko widok fragmentu, a nie pasek narzędzi;Nie ma potrzeby tworzenia fałszywej klasy ToolbarPreference w celu dodania jej do każdego pliku preferencji.xml (zobacz odpowiedź Gábora).
źródło
Oto biblioteka, którą stworzyłem, która jest oparta na kodzie AOSP, który dodaje odcienie zarówno do preferencji, jak i okien dialogowych, dodaje pasek akcji i obsługuje wszystkie wersje z API 7:
https://github.com/AndroidDeveloperLB/MaterialPreferenceLibrary
źródło
PreferenceScreen
takiegoPreferenceScreen
jak tenCóż, to nadal jest dla mnie problemem dzisiaj (18 listopada 2015). Wypróbowałem wszystkie rozwiązania z tego wątku, ale były dwie główne rzeczy, których nie mogłem rozwiązać:
Skończyło się więc na stworzeniu biblioteki z bardziej skomplikowanym rozwiązaniem. Zasadniczo musiałem wewnętrznie zastosować style do preferencji, jeśli używamy urządzenia sprzed wersji Lollipop, a także obsługiwałem zagnieżdżone ekrany przy użyciu niestandardowego fragmentu (przywracając całą zagnieżdżoną hierarchię przy użyciu klawisza PreferenceScreen ).
Biblioteka to ta: https://github.com/ferrannp/material-preferences
A jeśli interesuje Cię kod źródłowy (zbyt długi, aby go tutaj umieścić), to jest w zasadzie jego sedno: https://github.com/ferrannp/material-preferences/blob/master/library/src/main/ java / com / fnp / materialpreferences / PreferenceFragment.java
źródło