W Androidzie 8.0 wprowadziliśmy nową architekturę informacji dla aplikacji Ustawienia, uproszczenie porządkowania ustawień i ułatwi użytkownikom szybko znaleźć ustawienia i dostosować swoje urządzenia z Androidem. Android 9 wprowadził kilka ulepszeń, które zwiększają funkcjonalność ustawień i ułatwiają implementację.
Przykłady i źródło
Większość stron w sekcji Ustawienia jest obecnie implementowana za pomocą nowego frameworku. Dobrym przykładem jest DisplaySettings:packages/apps/Settings/src/com/android/settings/DisplaySettings.java
Poniżej znajdziesz ścieżki plików ważnych komponentów:
- kluczKategorii:
packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
- DashboardFragmentRegistry:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
- DashboardFragment:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java
- AbstractPreferenceController:
frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
- BasePreferenceController (wprowadzone w Androidzie 9):
packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java
Implementacja
Producentów urządzeń zachęcamy do dostosowania istniejącej architektury informacji w ustawieniach i do dodania dodatkowych stron ustawień w celu uwzględnienia funkcji partnerów. Przenoszenie ustawień ze starszej strony (implementowanej za pomocą funkcji SettingsPreferencePage
) na nową stronę (implementowaną za pomocą funkcji DashboardFragment
) może być skomplikowane. Preferencje z parametrów
starsza wersja strony prawdopodobnie nie jest zaimplementowana za pomocą tagu PreferenceController
.
Jeśli więc przenosisz preferencje ze starszej strony na nową, musisz utworzyć
PreferenceController
i przenieś kod do kontrolera przed
tworząc jej instancję w nowym formacie DashboardFragment
. Interfejsy API wymagane przez usługę PreferenceController
są opisane w jej nazwie i opisane w dokumentacji Javadoc.
Zdecydowanie zalecamy dodanie testu jednostkowego dla każdego elementu PreferenceController
.
Jeśli zmiana zostanie przesłana do AOSP, wymagany jest test jednostkowy.
Więcej informacji o pisaniu testów opartych na Robolectric znajdziesz w pliku readme packages/apps/Settings/tests/robotests/README.md
.
Architektura informacji w stylu wtyczki
Każdy element ustawień jest zaimplementowany jako preferencja. Ustawienia można łatwo przenosić z jednej strony na inną.
Aby ułatwić przenoszenie wielu ustawień, wprowadziliśmy Androida 8.0 fragment hosta w stylu wtyczki, który zawiera elementy ustawień. Elementy ustawień to modelowane jako kontrolery przypominające wtyczki. Dlatego stronę ustawień tworzy z pojedynczym fragmentem hosta i z kilkoma kontrolerami ustawień.
DashboardFragment
DashboardFragment
jest hostem sterowników ustawień w stylu wtyczki.
Fragment dziedziczy z PreferenceFragment
i zawiera elementy wywołujące, które służą do rozszerzania i aktualizowania zarówno statycznych, jak i dynamicznych list preferencji.
Ustawienia statyczne
Statyczna lista preferencji jest definiowana w XML za pomocą tagu <Preference>
. O
Implementacja DashboardFragment
korzysta z metody
getPreferenceScreenResId()
określa, który plik XML zawiera
statyczną listę ustawień do wyświetlenia.
Preferencje dynamiczne
Element dynamiczny reprezentuje kartę z zamierzeniem, która prowadzi do działania zewnętrznego lub wewnętrznego. Zwykle prowadzi ona do innej strony ustawień. Przykład:
„Google” element ustawienia na stronie głównej ustawień jest elementem dynamicznym. Dynamiczna,
elementy zostały zdefiniowane w AndroidManifest
(omówione poniżej) i zostały wczytane
za pomocą funkcji FeatureProvider
(zdefiniowanej jako
DashboardFeatureProvider
).
Ustawienia dynamiczne mają większe wymagania niż skonfigurowane statycznie. więc zwykle deweloperzy powinni wdrożyć ustawienie jako statyczne. Ustawienie dynamiczne może być jednak przydatne, gdy jest spełniony dowolny z tych warunków:
- To ustawienie nie jest wprowadzane bezpośrednio w aplikacji Ustawienia (np. wstrzyknięcie ustawienia zaimplementowanego przez aplikacje OEM lub operatora).
- To ustawienie powinno się pojawić na stronie głównej Ustawień.
- Masz już aktywność dla tego ustawienia i nie chcesz stosować dodatkowej konfiguracji statycznej.
Aby skonfigurować aktywność jako ustawienie dynamiczne:
- Oznacz działanie jako ustawienie dynamiczne, dodając do niego filtr intencji.
- Poinformuj aplikację Ustawienia, do której kategorii należy. Kategoria jest stałą wartością zdefiniowaną w pliku
CategoryKey
. - Opcjonalnie: po wyświetleniu ustawienia dodaj tekst podsumowania.
Oto przykład z aplikacji Ustawienia dla DisplaySettings
.
<activity android:name="Settings$DisplaySettingsActivity" android:label="@string/display_settings" android:icon="@drawable/ic_settings_display"> <!-- Mark the activity as a dynamic setting --> <intent-filter> <action android:name="com.android.settings.action.IA_SETTINGS" /> </intent-filter> <!-- Tell Settings app which category it belongs to --> <meta-data android:name="com.android.settings.category" android:value="com.android.settings.category.ia.homepage" /> <!-- Add a summary text when the setting is displayed --> <meta-data android:name="com.android.settings.summary" android:resource="@string/display_dashboard_summary"/> </activity>
Podczas renderowania fragment wymaga podania listy ustawień ze strony
Ustawienia XML i dynamiczne zdefiniowane w AndroidManifest
. Określa, czy
Elementy PreferenceController
są zdefiniowane w kodzie Javy lub pliku XML,
DashboardFragment
zarządza logiką obsługi każdego ustawienia
do PreferenceController
(opisane poniżej). Następnie są wyświetlane w interfejsie jako lista mieszana.
Kontroler preferencji
W tym rozdziale opisujemy różnice między implementacją PreferenceController
w Androidzie 9 a Androidem 8.x.
PreferenceController w Androidzie 9
PreferenceController
zawiera wszystkie funkcje logiczne interakcji z parametrem
w tym wyświetlanie, aktualizowanie, indeksowanie wyszukiwania itp.
Interfejs PreferenceController
jest zdefiniowany jako BasePreferenceController
. Zobacz kod w
packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java
Istnieje kilka podklas BasePreferenceController
, z których każda odpowiada określonemu stylowi interfejsu obsługiwanemu domyślnie przez aplikację Ustawienia. Na przykład TogglePreferenceController
ma interfejs API, który bezpośrednio odzwierciedla sposób interakcji użytkownika z interfejsem ustawień opartym na przełącznikach.
BasePreferenceController
ma interfejsy API takie jak
getAvailabilityStatus()
, displayPreference()
handlePreferenceTreeClicked(),
itp. Szczegółowa dokumentacja każdego
Interfejs API należy do klasy interfejsu.
Ograniczenie dotyczące implementacji zasad BasePreferenceController
(oraz
jej podklas, takich jak TogglePreferenceController
), jest to, że funkcja
podpis konstruktora musi pasować do jednej z tych wartości:
public MyController(Context context, String key) {}
public MyController(Context context) {}
Podczas instalowania preferencji do fragmentu panel oferuje metodę dołączania PreferenceController
przed czasem wyświetlania. W momencie instalacji
kontroler jest podłączony do fragmentu, aby wszystkie przyszłe zdarzenia były
wysłane na kontroler.
DashboardFragment
przechowuje listę
PreferenceController
na ekranie. W przypadku fragmentu
onCreate()
, wszystkie kontrolery są wywoływane dla instancji
getAvailabilityStatus()
, a jeśli zwraca wartość prawda,
Metoda displayPreference()
jest wywoływana w celu przetworzenia logiki wyświetlania.
getAvailabilityStatus()
jest też ważne, aby poinformować framework ustawień, które elementy są dostępne podczas wyszukiwania.
PreferenceController w Androidzie 8.x
PreferenceController
zawiera całą logikę interakcji z preferencją, w tym wyświetlanie, aktualizowanie, indeksowanie w wyszukiwarce itp.
Odpowiadając na interakcje z preferencjami, interfejs
PreferenceController
ma interfejsy API isAvailable()
,
displayPreference()
, handlePreferenceTreeClicked()
itd.
Szczegółową dokumentację każdego interfejsu API znajdziesz w klasie interfejsu.
Podczas instalowania preferencji do fragmentu panel oferuje metodę dołączania PreferenceController
przed czasem wyświetlania. Podczas instalacji kontroler jest podłączony do fragmentu, dzięki czemu wszystkie przyszłe zdarzenia są wysyłane do kontrolera.
DashboardFragment
przechowuje na ekranie listę elementów PreferenceControllers
. W miejscu onCreate()
fragmentu wywoływane są wszystkie kontrolery dla metody isAvailable()
, a jeśli zwróci ona wartość true, wywoływana jest metoda displayPreference()
, aby przetworzyć logikę wyświetlania.
Używanie DashboardFragment
Przenoszenie ustawienia z strony A na stronę B
Jeśli preferencja jest statyczna w pliku XML preferencji strony oryginalnej wykonaj procedurę przenoszenia statycznego na urządzeniu z Androidem. . W przeciwnym razie postępuj zgodnie z procedurą przenoszenia Dynamic w przypadku wersji na Androida.
Przenoszenie statyczne w Androidzie 9
- Znajdź preferowane pliki XML strony oryginalnej i miejsca docelowego
stronę. Te informacje znajdziesz w metodie
getPreferenceScreenResId()
strony. - Usuń ustawienie z pliku XML oryginalnej strony.
- Dodaj ustawienie do pliku XML strony docelowej.
- Usuń element
PreferenceController
odpowiadający tej opcji z implementacji Javy oryginalnej strony. Zazwyczaj jest tocreatePreferenceControllers()
. Kontroler może być zadeklarowany bezpośrednio w pliku XML.Uwaga: ustawienie może nie mieć wartości
PreferenceController
. - Utwórz instancję klasy
PreferenceController
w komponenciecreatePreferenceControllers()
na stronie docelowej. Jeśli ElementPreferenceController
jest zdefiniowany w pliku XML na starej stronie. Zdefiniuj go. w pliku XML dla nowej strony.
Dynamiczne przenoszenie na Androidzie 9
- Sprawdź, do której kategorii należy strona docelowa i pierwotna. Te informacje znajdziesz na stronie
DashboardFragmentRegistry
. - Otwórz plik
AndroidManifest.xml
, który zawiera ustawienie, które chcesz przenieść, i znajdź wpis Aktywność reprezentujący to ustawienie. - Ustaw wartość metadanych aktywności
com.android.settings.category
na klucz kategorii nowej strony.
Statyczne zmiany w wersjach Androida 8.x
- Znajdź pliki XML ustawień oryginalnej strony i strony docelowej. Te informacje możesz znaleźć za pomocą metody
- Usuń ustawienie z pliku XML oryginalnej strony.
- Dodaj ustawienie do pliku XML strony docelowej.
- Usuń
PreferenceController
dla tej preferencji w w implementacji języka Java dla strony oryginalnej. Zwykle jest wgetPreferenceControllers()
- Utwórz instancję klasy
PreferenceController
w blokugetPreferenceControllers()
na stronie docelowej.
getPreferenceScreenResId()
strony.
Uwaga: możliwe, że ustawienie nie ma
PreferenceController
Dynamiczne przenoszenie w wersjach Androida 8.x
- Sprawdź, do której kategorii należy strona docelowa i oryginalna. Więcej
te informacje w
DashboardFragmentRegistry
. - Otwórz plik
AndroidManifest.xml
zawierający Twoje ustawienie musisz przenieść i znaleźć wpis Aktywność reprezentujący to ustawienie. - Zmień wartość metadanych aktywności dla
com.android.settings.category
, a jako punkt wartości ustaw klucz kategorii nowej strony.
Tworzenie nowych ustawień na stronie
Jeśli ustawienie jest wymienione statycznie w pliku XML preferencji oryginalnej strony, wykonaj podaną niżej procedurę statyczną. W przeciwnym razie postępuj zgodnie z dynamiczną.
Tworzenie preferencji statycznych
- Znajdź pliki XML ustawień strony. Informacje na ten temat można znaleźć za pomocą metody getPreferenceScreenResId() strony.
- Dodaj nowy element preferencji w pliku XML. Upewnij się, że jest w niej unikalny
android:key
. -
W metodzie
getPreferenceControllers()
strony zdefiniujPreferenceController
dla tej preferencji.- W Androidzie 8.x i opcjonalnie 9 instancjuj obiekt
PreferenceController
dla tej preferencji w metodziecreatePreferenceControllers()
strony.Jeśli te ustawienia były już używane w innych miejscach, możliwe, że istnieje już dla nich
PreferenceController
. Możesz użyć ponowniePreferenceController
bez utworzenia nowego. -
Od Androida 9 możesz deklarować element
PreferenceController
w pliku XML obok preferencji. Na przykład:<Preference android:key="reset_dashboard" android:title="@string/reset_dashboard_title" settings:controller="com.android.settings.system.ResetPreferenceController"/>
- W Androidzie 8.x i opcjonalnie 9 instancjuj obiekt
Tworzenie preferencji dynamicznych
- Sprawdź, do której kategorii należy strona docelowa i oryginalna. Te informacje znajdziesz na stronie
DashboardFragmentRegistry
. - Utwórz nową aktywność na zajęciach
AndroidManifest
- Dodaj do nowego działania niezbędne metadane, aby zdefiniować ustawienie. Ustaw parametr
wartości metadanych dla pola
com.android.settings.category
na tę samą wartość zdefiniowane w kroku 1.
Utwórz nową stronę
- Utwórz nowy fragment, dziedziczący z poziomu
DashboardFragment
. - Zdefiniuj kategorię w parametrye
DashboardFragmentRegistry
.Uwaga: ten krok jest opcjonalny. Jeśli nie potrzebujesz dynamicznych preferencji na tej stronie, nie musisz podawać klucza kategorii.
- Postępuj zgodnie z instrukcjami dodawania ustawień wymaganych dla tej strony. Więcej informacji znajdziesz w sekcji Implementacja.
Weryfikacja
- Uruchom testy automatyczne w Ustawieniach. Wszystkie istniejące i nowe testy powinny przejść.
- Utwórz i zainstaluj Ustawienia, a potem ręcznie otwórz stronę, którą chcesz zmodyfikować. Strona powinna zostać zaktualizowana natychmiast.