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 trovare più facilmente le impostazioni per personalizzare i propri dispositivi Android. Android 9 ha introdotto alcuni miglioramenti per fornire maggiori funzionalità Impostazioni e un'implementazione più semplice.
Esempi e fonte
La maggior parte delle pagine delle Impostazioni è attualmente implementata con 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 l'architettura delle informazioni delle impostazioni esistente e di inserire altre pagine di impostazioni in base alle esigenze per soddisfare funzionalità specifiche dei partner. Il trasferimento delle preferenze dalla pagina precedente (implementata come SettingsPreferencePage
) a una nuova pagina (implementata mediante DashboardFragment
) può essere complicato. È probabile che la preferenza della
pagina precedente non sia implementata con un PreferenceController
.
Di conseguenza, quando sposti una preferenza da una pagina legacy a una nuova, devi creare una
PreferenceController
e spostare il codice nel controller prima
di confermarla nel nuovo DashboardFragment
. Le API richieste da PreferenceController
sono descritte nel nome e documentate in Javadoc.
Ti consigliamo vivamente di aggiungere un test delle unità per ogni PreferenceController
.
Se la modifica viene inviata ad AOSP, è necessario un test delle unità.
Per ulteriori informazioni su come scrivere test robotlettici, consulta il 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 facilmente spostata da una pagina all'altra.
Per semplificare lo spostamento di più impostazioni, Android 8.0 ha introdotto un frammento host in stile plug-in che contiene le voci delle impostazioni. Gli elementi delle impostazioni sono modellati come controller in stile plug-in. Pertanto, la pagina delle impostazioni viene creata da un singolo frammento host e da più controller di impostazioni.
Frammento Dashboard
DashboardFragment
è l'host dei controller delle preferenze in stile plug-in.
Il frammento eredita da PreferenceFragment
e ha hook per
espandere e aggiornare gli elenchi di preferenze statici e quelli dinamici.
Preferenze statiche
Viene definito un elenco di preferenze statico in XML utilizzando il tag <Preference>
. Un'implementazione
DashboardFragment
utilizza il
metodo getPreferenceScreenResId()
per definire quale file XML contiene
l'elenco statico di preferenze da visualizzare.
Preferenze dinamiche
Un elemento dinamico rappresenta un riquadro con l'intento, che genera un'attività esterna o interna. Di solito, l'intent porta a una pagina di impostazioni diversa. Ad esempio, l'elemento dell'impostazione "Google" nella home page Impostazioni è un elemento dinamico. Gli elementi dinamici sono definiti in AndroidManifest
(considerati di seguito) e caricati tramite un FeatureProvider
(definito come
DashboardFeatureProvider
).
Le impostazioni dinamiche hanno un peso maggiore rispetto a quelle configurate staticamente, pertanto gli sviluppatori dovrebbero implementarle normalmente. Tuttavia, l'impostazione dinamica può essere utile quando si verifica una delle seguenti condizioni:
- L'impostazione non è implementata direttamente nell'app Impostazioni (ad esempio inserendo un'impostazione implementata dalle app dell'OEM/dell'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 all'attività.
- Indica all'app Impostazioni a quale categoria appartiene. La categoria è una costante,
definita in
CategoryKey
. - (Facoltativo) Aggiungi un testo di riepilogo quando l'impostazione viene visualizzata.
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 dall'XML statico che dalle impostazioni dinamiche definite in AndroidManifest
. Sia che i
PreferenceController
siano definiti nel codice Java o in XML,
DashboardFragment
gestisce la logica di gestione di ogni impostazione
tramite PreferenceController
(discussa di seguito). Quindi vengono
visualizzate nell'interfaccia utente sotto forma di elenco misto.
PreferenceController
Esistono differenze tra l'implementazione di PreferenceController
in Android 9 e Android 8.x, come descritto in questa
sezione.
PreferenceController nella release di Android 9
Un PreferenceController
contiene tutta la logica per interagire con la preferenza, tra cui visualizzazione, aggiornamento, indicizzazione della ricerca e così via.
L'interfaccia di PreferenceController
è definita come
BasePreferenceController
. Ad esempio, consulta il codice in
packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java
Esistono diverse sottoclassi di BasePreferenceController
, ciascuna
mappata a uno stile di UI specifico supportato per impostazione predefinita dall'app Impostazioni. Ad
esempio, TogglePreferenceController
ha un'API che mappa direttamente
al modo in cui l'utente deve interagire con una UI delle preferenze basata su attivazione/disattivazione.
BasePreferenceController
include API quali
getAvailabilityStatus()
, displayPreference()
,
handlePreferenceTreeClicked(),
e così via. La documentazione dettagliata per ciascuna
API è disponibile nella classe dell'interfaccia.
Una limitazione relativa all'implementazione di BasePreferenceController
(e delle relative 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 collegare un PreferenceController
prima del tempo di visualizzazione. Al momento dell'installazione,
il controller è collegato al frammento, in modo che tutti gli eventi futuri pertinenti vengano
inviati al controller.
DashboardFragment
mantiene un elenco di
PreferenceController
sullo schermo. Nel valore onCreate()
del frammento, tutti i controller vengono richiamati per il metodo getAvailabilityStatus()
e, se restituisce true, displayPreference()
viene richiamato per elaborare la logica di visualizzazione.
getAvailabilityStatus()
è importante anche per indicare al framework
Impostazioni quali elementi sono disponibili durante la ricerca.
PreferenceController nelle release di Android 8.x
Un PreferenceController
contiene tutta la logica per interagire con la preferenza, tra cui visualizzazione, aggiornamento, indicizzazione della ricerca e così via.
In corrispondenza delle interazioni con le preferenze, l'interfaccia di
PreferenceController
include 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 per il frammento, la dashboard fornisce un metodo
per collegare un PreferenceController
prima del tempo di visualizzazione. Al momento dell'installazione,
il controller è collegato al frammento, in modo che tutti gli eventi futuri pertinenti vengano
inviati al controller.
DashboardFragment
mantiene un elenco di PreferenceControllers
sullo schermo. All'elemento onCreate()
del frammento, tutti i controller vengono richiamati per il metodo isAvailable()
e, se restituisce true, displayPreference()
viene richiamato per elaborare la logica di visualizzazione.
Utilizza 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 statico per la release di Android riportata di seguito. In caso contrario, segui la procedura di spostamento dinamico per la release di 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 tramite il 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 dall'implementazione Java della pagina originale. Di solito si trova increatePreferenceControllers()
. Il controller può essere dichiarato direttamente in XML.Nota: la preferenza potrebbe non avere un
PreferenceController
. - Crea un'istanza per
PreferenceController
nel valorecreatePreferenceControllers()
della pagina di destinazione. SePreferenceController
è definito in XML nella vecchia pagina, definiscilo anche 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
trovare queste informazioni nella pagina
DashboardFragmentRegistry
. - Apri il file
AndroidManifest.xml
che contiene l'impostazione da spostare e trova la voce Attività che rappresenta questa impostazione. - Imposta il valore dei metadati dell'attività per
com.android.settings.category
sulla 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 tramite il 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
PreferenceController
nel valoregetPreferenceControllers()
della pagina di destinazione.
getPreferenceScreenResId()
della pagina.
Nota: è possibile che la preferenza non abbia un
PreferenceController
.
Lo 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 da spostare e trova 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 di 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 la procedura dinamica.
Crea una preferenza statica
- Individua i file XML delle preferenze per la pagina. Puoi trovare queste informazioni nel metodo getPreferenceScreenResId() della pagina.
- Aggiungi un nuovo elemento Preferenza nel file XML. Assicurati che abbia un valore
android:key
univoco. -
Definisci un
PreferenceController
per questa preferenza nel metodogetPreferenceControllers()
della pagina.- In Android 8.x e facoltativamente in Android 9,
identifica un
PreferenceController
per questa preferenza nel metodocreatePreferenceControllers()
della pagina.Se questa preferenza esisteva già in altri luoghi, è possibile che sia già presente un
PreferenceController
. Puoi riutilizzare ilPreferenceController
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,
identifica un
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 valore dei metadati per
com.android.settings.category
sullo stesso valore definito 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 hai bisogno di 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 (esistenti e nuovi) devono essere superati.
- Crea e installa le impostazioni, quindi apri manualmente la pagina da modificare. La pagina dovrebbe aggiornarsi immediatamente.