Android 8.0 ha introdotto una nuova architettura delle informazioni per l'app Impostazioni per semplificare il modo in cui le impostazioni sono organizzate e consentire agli utenti di trovarle più facilmente per personalizzare i propri dispositivi Android. Android 9 ha introdotto alcuni miglioramenti per fornire Funzionalità delle impostazioni e implementazione più semplice.
Esempi e fonte
Al momento, la maggior parte delle pagine in Impostazioni è implementata utilizzando il nuovo framework. Un buon esempio è DisplaySettings:packages/apps/Settings/src/com/android/settings/DisplaySettings.java
Di seguito sono elencati i percorsi dei file per i componenti importanti:
- CategoryKey:
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 (introdotto in Android 9):
packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java
Implementazione
Consigliamo ai produttori di dispositivi di adattare le informazioni delle Impostazioni esistenti
e inserire altre pagine di impostazioni in base alle esigenze
funzioni specifiche per i partner. Lo spostamento delle preferenze dalla pagina precedente (implementata come
SettingsPreferencePage
) a una nuova pagina (implementata utilizzando
DashboardFragment
) può essere complicato. La preferenza
pagina precedente probabilmente non è implementata con un PreferenceController
.
Perciò, quando sposti una preferenza da una pagina legacy a una nuova, dovrai creare una
PreferenceController
e sposta il codice nel controller prima
creando un'istanza nel nuovo DashboardFragment
. Le API che
I requisiti di PreferenceController
sono descritti nel nome e
documentati in Javadoc.
Ti consigliamo vivamente di aggiungere un test delle unità per ogni PreferenceController
.
Se la modifica viene inviata ad AOSP, è necessario un test unitario.
Per ulteriori informazioni su come scrivere test robotici, consulta la
file Leggimi packages/apps/Settings/tests/robotests/README.md
.
Architettura delle informazioni stile plug-in
Ogni elemento delle impostazioni viene implementato come una preferenza. Una preferenza può essere sono state spostate da una pagina all'altra.
Per semplificare il trasferimento di più impostazioni, Android 8.0 ha introdotto un frammento host in stile plug-in contenente gli elementi di impostazioni. Le voci di impostazioni sono modellati come controller in stile plug-in. Pertanto, una pagina delle impostazioni viene creata un singolo frammento host e più controller di impostazione.
DashboardFragment
DashboardFragment
è l'host dei controller delle preferenze in stile plug-in.
Il frammento eredita da PreferenceFragment
e ha hook a
espandere e aggiornare sia gli elenchi di preferenze statici sia quelli dinamici.
Preferenze statiche
Viene definito un elenco di preferenze statico in XML utilizzando il tag <Preference>
. Un'implementazione di DashboardFragment
utilizza il metodo getPreferenceScreenResId()
per definire quale file XML contiene l'elenco statico delle preferenze da visualizzare.
Preferenze dinamiche
Un elemento dinamico rappresenta un riquadro con intent, che rimanda a un'attività interna o esterna. In genere, l'intent indirizza a una pagina di impostazioni diversa. Ad esempio:
Google nella home page Impostazioni è un elemento dinamico. Dinamico
elementi sono definiti in AndroidManifest
(esaminati di seguito) e caricati
attraverso un FeatureProvider
(definito come
DashboardFeatureProvider
).
Le impostazioni dinamiche sono più complesse di quelle configurate in modo statico, pertanto in genere gli sviluppatori devono implementarle come impostazioni statiche. Tuttavia, l'impostazione dinamica può essere utile quando si verifica una delle seguenti condizioni:
- L'impostazione non è implementata direttamente nell'app Impostazioni (ad esempio, l'inserimento di un'impostazione implementata dalle app OEM/operatore).
- L'impostazione viene visualizzata nella home page delle Impostazioni.
- Hai già un'attività per l'impostazione e non vuoi implementare la configurazione statica aggiuntiva.
Per configurare un'attività come impostazione dinamica:
- Contrassegna l'attività come impostazione dinamica aggiungendo un filtro per intent al attività.
- Indica all'app Impostazioni a quale categoria appartiene. La categoria è una costante,
definita in
CategoryKey
. - (Facoltativo) Aggiungi il testo del riepilogo quando viene visualizzata l'impostazione.
Ecco un esempio tratto dall'app Impostazioni per 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>
Al momento del rendering, il frammento richiede un elenco di preferenze sia per le immagini statiche
XML e impostazioni dinamiche definite in AndroidManifest
. Indipendentemente dal fatto che i parametri PreferenceController
siano definiti in codice Java o in XML, DashboardFragment
gestisce la logica di gestione di ogni impostazione tramite PreferenceController
(descritto di seguito). Quindi vengono
visualizzate nell'interfaccia utente sotto forma di elenco misto.
PreferenceController
Ci sono differenze tra l'implementazione di PreferenceController
su Android 9 e Android 8.x, come descritto
.
PreferenceController nella release di Android 9
Un PreferenceController
contiene tutta la logica per interagire con
preferenza, tra cui visualizzazione, aggiornamento, indicizzazione della ricerca e così via.
L'interfaccia di PreferenceController
è definita come
BasePreferenceController
. Ad esempio, vedi il codice
packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java
Esistono diverse sottoclassi di BasePreferenceController
, ciascuna
mappato a uno stile di UI specifico supportato per impostazione predefinita dall'app Impostazioni. Per
Ad esempio, TogglePreferenceController
ha un'API che mappa direttamente
a come l'utente deve interagire con
un'interfaccia utente preferita basata su attivazione/disattivazione.
BasePreferenceController
ha API come
getAvailabilityStatus()
, displayPreference()
,
handlePreferenceTreeClicked(),
e così via. La documentazione dettagliata di ogni
API è nella classe dell'interfaccia.
Una limitazione all'implementazione di BasePreferenceController
(e dei suoi sottoclassi come TogglePreferenceController
) è che la firma del costruttore deve corrispondere a una delle seguenti:
public MyController(Context context, String key) {}
public MyController(Context context) {}
Durante l'installazione di una preferenza per il frammento, la dashboard fornisce un metodo per
allega un PreferenceController
prima del tempo di visualizzazione. Al momento dell'installazione, il controller viene collegato al frammento in modo che tutti gli eventi pertinenti futuri vengano inviati al controller.
DashboardFragment
conserva un elenco di
PreferenceController
sullo schermo. All'inizio del frammento
onCreate()
, tutti i controller sono richiamati per
getAvailabilityStatus()
e, se restituisce true,
displayPreference()
viene richiamato per elaborare la logica di visualizzazione.
getAvailabilityStatus()
è importante anche indicare alle Impostazioni
per capire quali elementi sono disponibili durante la ricerca.
PreferenceController nelle release di Android 8.x
Un PreferenceController
contiene tutta la logica per interagire con
dei dati, tra cui visualizzazione, aggiornamento e indicizzazione della ricerca. ecc.
Corrispondenti alle interazioni delle preferenze, l'interfaccia di
PreferenceController
ha le API isAvailable()
,
displayPreference()
, handlePreferenceTreeClicked()
e così via.
La documentazione dettagliata su ciascuna API è disponibile nella classe dell'interfaccia.
Durante l'installazione di una preferenza nel frammento, la dashboard fornisce un metodo per collegare un PreferenceController
prima del tempo di visualizzazione. Al momento dell'installazione, il controller viene collegato al frammento in modo che tutti gli eventi pertinenti futuri vengano inviati al controller.
DashboardFragment
mantiene un elenco di PreferenceControllers
nella schermata. In corrispondenza del valore onCreate()
del frammento, tutti
vengono richiamati per il metodo isAvailable()
e, se
restituisce true, displayPreference()
viene richiamato per elaborare la visualizzazione
logica.
Utilizzare DashboardFragment
Spostare una preferenza dalla pagina A alla pagina B
Se la preferenza è elencata in modo statico nel file XML delle preferenze della pagina originale, segui la procedura di spostamento Statica per la release di Android riportata di seguito. In caso contrario, segui la procedura di trasferimento dinamico per la tua release Android.
Spostamento statico in Android 9
- Trova i file XML delle preferenze per la pagina originale e la pagina di destinazione. Puoi trovare queste informazioni nel metodo
getPreferenceScreenResId()
della pagina. - Rimuovi la preferenza dal file XML della pagina originale.
- Aggiungi la preferenza al file XML della pagina di destinazione.
- Rimuovi
PreferenceController
per questa preferenza dal l'implementazione Java della pagina originale. Di solito si trova increatePreferenceControllers()
. Il controller potrebbe essere dichiarato direttamente in XML.Nota: alla preferenza potrebbe non essere associato un
PreferenceController
. - Crea un'istanza di
PreferenceController
nelcreatePreferenceControllers()
della pagina di destinazione. SePreferenceController
è definito in XML nella vecchia pagina, definiscilo in XML anche per la nuova pagina.
Trasloco dinamico in Android 9
- Trova la categoria ospitata dalla pagina originale e dalla pagina di destinazione. Puoi
puoi trovare queste informazioni in
DashboardFragmentRegistry
. - Apri il file
AndroidManifest.xml
che contiene l'impostazione spostalo e individua la voce Attività che rappresenta questa impostazione. - Imposta il valore dei metadati dell'attività per
com.android.settings.category
alla chiave di categoria della nuova pagina.
Spostamento statico nelle release di Android 8.x
- Trova i file XML delle preferenze per la pagina originale e la pagina di destinazione. Puoi trovare queste informazioni nel metodo
- Rimuovi la preferenza dal file XML della pagina originale.
- Aggiungi la preferenza al file XML della pagina di destinazione.
- Rimuovi
PreferenceController
per questa preferenza nell'implementazione Java della pagina originale. Di solito si trova ingetPreferenceControllers()
. - Crea un'istanza per il campo
PreferenceController
nel taggetPreferenceControllers()
.
getPreferenceScreenResId()
della pagina.
Nota: è possibile che per la preferenza non sia associato un
PreferenceController
.
Spostamento dinamico nelle release di Android 8.x
- Trova la categoria ospitata dalla pagina originale e dalla pagina di destinazione. Puoi trovare queste informazioni in
DashboardFragmentRegistry
. - Apri il file
AndroidManifest.xml
che contiene l'impostazione spostalo e individua la voce Attività che rappresenta questa impostazione. - Modifica il valore dei metadati dell'attività per
com.android.settings.category
, imposta il punto di valore sulla chiave della categoria della nuova pagina.
Creare una nuova preferenza in una pagina
Se la preferenza è elencata in modo statico nel file XML delle preferenze della pagina originale segui la procedura statica riportata di seguito. In caso contrario, segui le Dynamic.
Crea una preferenza statica
- Trova i file XML delle preferenze per la pagina. Puoi trovare queste informazioni dal metodo getPreferenceScreenResId() della pagina.
- Aggiungi un nuovo elemento Preference nel file XML. Assicurati che abbia un valore
android:key
univoco. -
Definisci un
PreferenceController
per questa preferenza nella sezione MetodogetPreferenceControllers()
.- In Android 8.x e facoltativamente in Android 9:
crea un'istanza
PreferenceController
per questa preferenza nel metodocreatePreferenceControllers()
della pagina.Se questa preferenza esisteva già in altri luoghi, è possibile che esista già un
PreferenceController
. Puoi riutilizzarePreferenceController
senza crearne uno nuovo. -
A partire da Android 9, puoi scegliere di dichiarare
PreferenceController
in XML accanto alla preferenza. Ad esempio:<Preference android:key="reset_dashboard" android:title="@string/reset_dashboard_title" settings:controller="com.android.settings.system.ResetPreferenceController"/>
- In Android 8.x e facoltativamente in Android 9:
crea un'istanza
Creare una preferenza dinamica
- Trova la categoria ospitata dalla pagina originale e dalla pagina di destinazione. Puoi trovare queste informazioni in
DashboardFragmentRegistry
. - Crea una nuova attività in
AndroidManifest
- Aggiungi i metadati necessari alla nuova attività per definire l'impostazione. Imposta il parametro
valore dei metadati per
com.android.settings.category
sullo stesso valore definita nel passaggio 1.
Crea una nuova pagina
- Crea un nuovo frammento, ereditando da
DashboardFragment
. - Definisci la relativa categoria in
DashboardFragmentRegistry
.Nota: questo passaggio è facoltativo. Se non ti occorre preferenze dinamiche in questa pagina, non è necessario fornire una chiave di categoria.
- Segui i passaggi per aggiungere le impostazioni necessarie per questa pagina. Per ulteriori informazioni, consulta la sezione Implementazione.
Convalida
- Esegui i test robolectrici nelle Impostazioni. Tutti i test nuovi ed esistenti devono essere superati.
- Compila e installa Impostazioni, quindi apri manualmente la pagina da modificare. La pagina dovrebbe aggiornarsi immediatamente.