O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Arquitetura de informação

O Android 8.0 introduziu uma nova arquitetura de informações para o aplicativo Configurações para simplificar a maneira como as configurações são organizadas e tornar mais fácil para os usuários encontrarem rapidamente as configurações para personalizar seus dispositivos Android. O Android 9 introduziu algumas melhorias para fornecer mais funcionalidade de configurações e implementação mais fácil.

Exemplos e fonte

A maioria das páginas em Configurações são atualmente implementadas usando a nova estrutura. Um bom exemplo é DisplaySettings: packages/apps/Settings/src/com/android/settings/DisplaySettings.java

Os caminhos de arquivos para componentes importantes estão listados abaixo:

  • 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 (introduzido no Android 9): packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java

Implementação

Os fabricantes de dispositivos são incentivados a adaptar a arquitetura de informações de configurações existente e inserir páginas de configurações adicionais conforme necessário para acomodar recursos específicos do parceiro. Movendo as preferências a partir da página legado (implementado como SettingsPreferencePage ) para uma nova página (implementadas usando DashboardFragment ) pode ser complicado. A preferência da página legado provavelmente não é implementado com um PreferenceController .

Assim, ao mover um preferências de uma página de legado para uma nova página, você precisa criar um PreferenceController e mover o código para o controlador antes de instanciar-la no novo DashboardFragment . As APIs que PreferenceController requer são descritos em seu nome e documentado em Javadoc.

É altamente recomendável adicionar um teste de unidade para cada PreferenceController . Se a alteração for enviada ao AOSP, será necessário um teste de unidade. Para obter mais informações sobre como escrever testes baseados Robolectric, consulte o arquivo readme packages/apps/Settings/tests/robotests/README.md .

Arquitetura de informação estilo plug-in

Cada item de configuração é implementado como uma preferência. Uma preferência pode ser facilmente movida de uma página para outra.

Para facilitar a movimentação de várias configurações, o Android 8.0 introduziu um fragmento de host em estilo plug-in que contém itens de configuração. Os itens de configuração são modelados como controladores de estilo plug-in. Portanto, uma página de configurações é construída por um único fragmento de host e vários controladores de configuração.

DashboardFragment

DashboardFragment é o anfitrião de controladores de preferências de estilo plugin. Os herda fragmento de PreferenceFragment e tem ganchos para expandir e atualizar ambas as listas de preferências estáticos e listas de preferência dinâmicos.

Preferências estáticas

A lista de preferência estática é definida em XML usando o <Preference> tag. A DashboardFragment implementação usa o getPreferenceScreenResId() método para definir qual arquivo XML contém a lista estática de preferências para mostrar.

Preferências dinâmicas

Um item dinâmico representa um bloco com intenção, levando a uma atividade externa ou interna. Normalmente, a intenção leva a uma página de configuração diferente. Por exemplo, o item de configuração "Google" na página inicial de Configurações é um item dinâmico. Itens dinâmicos são definidos em AndroidManifest (discutido abaixo) e carregada através de uma FeatureProvider (definido como DashboardFeatureProvider ).

As configurações dinâmicas são mais pesadas do que as configurações definidas estaticamente, portanto, normalmente os desenvolvedores devem implementar a configuração como estática. No entanto, a configuração dinâmica pode ser útil quando qualquer uma das seguintes condições for verdadeira:

  • A configuração não é implementada diretamente no aplicativo Configurações (como inserir uma configuração implementada por aplicativos OEM / Operadora).
  • A configuração deve aparecer na página inicial de Configurações.
  • Você já tem uma atividade para a configuração e não deseja implementar a configuração estática extra.

Para configurar uma atividade como uma configuração dinâmica, faça o seguinte:

  • Marque a atividade como uma configuração dinâmica adicionando um filtro de intenção à atividade.
  • Informe ao aplicativo Configurações a qual categoria ele pertence. A categoria é uma constante, definida em CategoryKey .
  • Opcional: adicione texto de resumo quando a configuração for exibida.

Aqui está um exemplo tirado de aplicativo Configurações para 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>

Na hora de renderizar, o fragmento vai pedir uma lista de preferências de ambos XML estático e as configurações dinâmicas definidas no AndroidManifest . Se os PreferenceController s são definidos em código Java ou em XML, DashboardFragment administra a lógica de tratamento de cada configuração através PreferenceController (discutido abaixo). Em seguida, eles são exibidos na IU como uma lista mista.

PreferenceController

Existem diferenças entre a implementação PreferenceController no Android 9 e Android 8.x, como descrito nesta seção.

PreferenceController na versão Android 9

A PreferenceController contém toda a lógica para interagir com a preferência, incluindo a exibição, atualização, indexação de pesquisa, etc.

A interface de PreferenceController é definido como BasePreferenceController . Por exemplo, veja o código em packages/apps/Settings/src/com/android/settings/core/ BasePreferenceController.java

Existem várias subclasses de BasePreferenceController , cada um mapeamento para um estilo UI específica que suporta o aplicativo Ajustes por padrão. Por exemplo, TogglePreferenceController tem uma API que mapeia diretamente para a forma como o usuário deve interagir com uma preferência de interface do usuário baseada em alternância.

BasePreferenceController tem APIs como getAvailabilityStatus() , displayPreference() , handlePreferenceTreeClicked(), etc. A documentação detalhada para cada API está na classe interface.

A restrição à implementação BasePreferenceController (e suas subclasses, como TogglePreferenceController ) é que a assinatura de construtor deve coincidir com um dos seguintes procedimentos:

  • public MyController(Context context, String key) {}
  • public MyController(Context context) {}

Ao instalar uma preferência para o fragmento, painel fornece um método para fixar um PreferenceController antes de tempo de exibição. No momento da instalação, o controlador é conectado ao fragmento para que todos os eventos futuros relevantes sejam enviados ao controlador.

DashboardFragment mantém uma lista de PreferenceController s na tela. No do fragmento onCreate() , todos os controladores são invocados para o getAvailabilityStatus() método, e se ele retorna true, displayPreference() é chamado para lógica de exibição processo. getAvailabilityStatus() também é importante para dizer ao quadro Configurações quais itens estão disponíveis durante a pesquisa.

PreferenceController em versões do Android 8.x

A PreferenceController contém toda a lógica para interagir com a preferência, incluindo a exibição, atualização, indexação de pesquisa. etc.

Correspondente às interações de preferência, a interface de PreferenceController tem APIs isAvailable() , displayPreference() , handlePreferenceTreeClicked() etc. documentação detalhada sobre cada API pode ser encontrada na classe interface.

Ao instalar uma preferência para o fragmento, painel fornece um método para fixar um PreferenceController antes de tempo de exibição. No momento da instalação, o controlador é conectado ao fragmento para que todos os eventos futuros relevantes sejam enviados ao controlador.

DashboardFragment mantém uma lista de PreferenceControllers na tela. No do fragmento onCreate() , todos os controladores são invocados para o isAvailable() método, e se ele retorna true, displayPreference() é chamado para lógica de exibição processo.

Usando DashboardFragment

Movendo uma preferência da página A para B

Se a preferência é estaticamente listados no arquivo de preferências XML da página original, siga o procedimento movimento estático para o seu lançamento Android abaixo. Caso contrário, siga o procedimento de movimento dinâmico para sua liberação Android.

Movimento estático no Android 9

  1. Encontre os arquivos XML de preferência para a página original e a página de destino. Você pode encontrar essa informação a partir da página getPreferenceScreenResId() método.
  2. Remova a preferência do XML da página original.
  3. Adicione a preferência ao XML da página de destino.
  4. Remova o PreferenceController para essa preferência de implementação Java da página original. Geralmente é no createPreferenceControllers() . O controlador pode ser declarado em XML diretamente.

    Nota: A preferência pode não ter uma PreferenceController .

  5. Instanciar o PreferenceController em da página de destino createPreferenceControllers() . Se o PreferenceController é definida em XML na página de idade, defini-lo em XML para a nova página também.

Movimento dinâmico no Android 9

  1. Encontre em qual categoria a página original e de destino hospeda. Você pode encontrar essa informação em DashboardFragmentRegistry .
  2. Abra o AndroidManifest.xml arquivo que contém a configuração que você precisa para mover-se e encontrar a entrada de Atividade representando esta definição.
  3. Definir valor de metadados da atividade para com.android.settings.category a chave de categoria da nova página.

Movimento estático em versões do Android 8.x

  1. Encontre os arquivos XML de preferência para a página original e a página de destino.
  2. Você pode encontrar essa informação a partir da página getPreferenceScreenResId() método.
  3. Remova a preferência no XML da página original.
  4. Adicione a preferência ao XML da página de destino.
  5. Remova o PreferenceController para essa preferência na implementação Java da página original. Geralmente é no getPreferenceControllers() .
  6. Nota: É possível a preferência não tem um PreferenceController .

  7. Instanciar o PreferenceController em da página de destino getPreferenceControllers() .

Movimento dinâmico em versões do Android 8.x

  1. Encontre em qual categoria a página original e de destino hospeda. Você pode encontrar essa informação em DashboardFragmentRegistry .
  2. Abra o AndroidManifest.xml arquivo que contém a configuração que você precisa para mover-se e encontrar a entrada de Atividade representando esta definição.
  3. Alterar valor de metadados da atividade para com.android.settings.category , definir o ponto de valor a chave de categoria da nova página.

Criação de uma nova preferência em uma página

Se a preferência é estaticamente listadas na arquivo XML preferência do página original, siga o procedimento estático abaixo. Caso contrário, siga o procedimento dinâmico.

Criação de uma preferência estática

  1. Encontre os arquivos XML de preferência para a página. Você pode encontrar essas informações no método getPreferenceScreenResId () da página.
  2. Adicione um novo item de preferência no XML. Certifique-se de que tem um único android:key .
  3. Definir um PreferenceController para essa preferência na da página getPreferenceControllers() método.
    • Em 8.X Android e opcionalmente em Android 9, instanciar um PreferenceController para esta preferência na página de createPreferenceControllers() método.

      Se essa preferência já existia em outros lugares, é possível que já existe uma PreferenceController para ele. Você pode reutilizar o PreferenceController sem construir um novo.

    • A partir de Android 9, você pode optar por declarar a PreferenceController em XML ao lado da preferência. Por exemplo:
      <Preference
              android:key="reset_dashboard"
              android:title="@string/reset_dashboard_title"
              settings:controller="com.android.settings.system.ResetPreferenceController"/>
      

Criação de uma preferência dinâmica

  1. Encontre em qual categoria a página original e de destino hospeda. Você pode encontrar essa informação em DashboardFragmentRegistry .
  2. Criar uma nova atividade em AndroidManifest
  3. Adicione os metadados necessários à nova atividade para definir a configuração. Definir o valor de metadados para com.android.settings.category para o mesmo valor definido no passo 1.

Crie uma nova página

  1. Criar um novo fragmento, herdando de DashboardFragment .
  2. Defina sua categoria em DashboardFragmentRegistry .

    Nota: Esta etapa é opcional. Se você não precisa de nenhuma preferência dinâmica nesta página, não precisa fornecer uma chave de categoria.

  3. Siga as etapas para adicionar as configurações necessárias para esta página. Para mais informações, consulte a Implementação seção.

Validação

  • Execute os testes robolétricos em Configurações. Todos os testes existentes e novos devem ser aprovados.
  • Crie e instale as configurações e, em seguida, abra manualmente a página que está sendo modificada. A página deve ser atualizada imediatamente.