Embora os blocos e widgets mostrem seu conteúdo em uma superfície de sistema remoto, a criação deles exige abordagens distintas. Migrar seu bloco para um widget significa fazer a transição da geração de layout rígido para uma interface dinâmica e declarativa, desbloqueando novos recursos e um modelo de desenvolvimento simplificado.
Escolha sua estratégia de implementação
Se você estiver migrando um app que mantém um bloco legado, decida como ele vai fornecer conteúdo ao sistema. Enquanto os widgets novos precisam usar um único serviço de widget, os apps com blocos atuais precisam escolher entre manter os dois serviços ou consolidar em um único serviço de widget.
Recomendado: serviço duplo (bloco + widget)
Manter um bloco e um widget é o caminho recomendado para todos os apps que têm um bloco. Fornecer dois serviços distintos oferece a melhor experiência do usuário possível em diferentes dispositivos.
- Serviço de bloco: estenda
TileServicee declare um filtro de intent paraandroidx.wear.tiles.action.BIND_TILE_PROVIDER. - Serviço de widget:estenda
GlanceWearWidgetServicee declare um filtro de intent paraandroidx.glance.wear.action.BIND_WIDGET_PROVIDER. - Agrupamento lógico: use o atributo
groupna configuração do widget para vincular a nova implementação aoTileServiceatual. Isso permite que o sistema os reconheça como um único componente lógico e migre automaticamente o slot de carrossel do usuário para o novo widget no Wear OS 7 ou mais recente.
Comportamento do sistema para configuração de serviço duplo :
| Capacidade do SO / dispositivo | Experiência resultante |
|---|---|
| Wear OS 3 | O bloco é usado |
| Wear OS 4, 5, 6 | O bloco é usado |
| Wear OS 7 (sem suporte à altura parcial, por exemplo, Pixel Watch) | O bloco é usado |
| Wear OS 7 (suporte à altura parcial, por exemplo, Galaxy Watch) | O widget é usado |
Alternativa: serviço único (somente widget)
Um único serviço processa os dois protocolos. Embora essa abordagem seja mais rápida de implementar, ela depende de um modo de compatibilidade para "adaptar" o widget a um bloco em dispositivos que executam versões mais antigas do Wear OS.
Se você escolher essa abordagem:
- Especifique os dois filtros de intent:seu serviço precisa incluir filtros de intent para
androidx.wear.tiles.action.BIND_TILE_PROVIDEReandroidx.glance.wear.action.BIND_WIDGET_PROVIDER. Isso garante que o widget seja mostrado em superfícies de blocos no Wear 4, 5, 6 e 7 (quando necessário). - Mantenha o nome do serviço atual (para upgrades perfeitos) : se você estiver substituindo um bloco ativo, manter o mesmo nome de classe de serviço garante que os usuários que têm o bloco no carrossel vão vê-lo atualizar automaticamente para o novo widget. Embora o Wear OS 7 use o atributo
groupno XML de configuração do widget para vincular logicamente diferentes componentes, as versões do Wear OS anteriores à 7 dependem do nome do serviço para identificá-los como o "mesmo" componente. Se você preferir usar um novo nome de serviço, seu app ainda vai funcionar perfeitamente. No entanto, os usuários em dispositivos que executam o Wear OS versão 6 ou anterior precisarão adicionar o widget ao carrossel manualmente.
Comportamento do sistema para configuração de serviço único :
| Capacidade do SO / dispositivo | Experiência resultante |
|---|---|
| Wear OS 3 | Indisponível |
| Wear OS 4, 5, 6 | O widget é mostrado como um bloco de tela cheia |
| Wear OS 7 (sem suporte à altura parcial) | O widget é traduzido para um bloco |
| Wear OS 7 (suporte à altura parcial) | O widget é usado |
*Requer o renderizador 1.6 ou mais recente.
Dicas de tradução da interface
Ao traduzir a interface do ProtoLayout (blocos) para o Remote Compose (widgets), o modelo mental muda de builders de layout imperativos para uma arquitetura baseada em estado e no Compose, em que as atualizações da interface são processadas por recomposição. Tenha em mente os seguintes princípios:
- Adote a interface declarativa:substitua os builders imperativos do ProtoLayout
(
LayoutElementBuilders) por equivalentes declarativos do Remote Compose, comoRemoteText,RemoteColumneRemoteBox. - Concentre-se no conteúdo principal (
mainSlot) : os widgets de altura parcial (por exemplo, tipos de contêinerSMALLeLARGE) fornecem uma superfície focada e visível. Em vez de portar um layout de bloco denso e de tela cheia, simplifique o design para enfatizar as informações principais na área de conteúdo principal. - Redesenhe ações alinhadas à borda: na arquitetura de blocos, os componentes que se ajustam à tela,
como o
EdgeButtoneram ancorados a umbottomSlotdedicado. Como os widgets de altura parcial são integrados diretamente a uma superfície de rolagem vertical, esse paradigma fixo debottomSlotnão existe mais. Como os botões alinhados à borda costumam servir como ações principais de destaque, a migração exige um redesenho deliberado da interface, em vez de uma troca direta de componentes. Avalie estratégias alternativas de UX para suas ações principais:- Ações inline: integre um
RemoteButtoninline diretamente no layoutmainSlot. - Toques de contêiner: consolide a interação tornando todo o
contêiner de widget clicável usando um
PendingIntentAction. - Pivô de conteúdo:reavalie o foco do widget. Sem um slot de ação dedicado, considere mostrar dados mais ricos e visíveis e confiar em um único toque para abrir o aplicativo completo, em vez de isolar ações específicas na superfície do widget.
- Ações inline: integre um
- Migre o processamento de eventos (ações x lambdas) : os blocos dependem de interações (como
LoadAction) que acionam callbacks de serviço completos para atualizar a interface. Os widgets do Wear são orientados pelo lado do cliente. As lambdas padrão do Compose não podem ser executadas remotamente. Em vez disso, forneça ações declarativas serializáveis (comoValueChangeouPendingIntentAction). Combine-as com o estado declarativo (por exemplo,rememberMutableRemoteInt) para oferecer suporte a atualizações instantâneas da interface sem viagens de ida e volta do app. - Adapte dimensões e tipos: ao migrar dimensões de layout, prefira
a resolução de layout adiada usando
RemoteDp(por exemplo,10.rdp) em vez doDppadrão. Isso garante que o renderizador do sistema calcule corretamente os valores de pixel no tempo de exibição. Da mesma forma, use funções de extensão do Remote Compose (.rcparaColor,.rsparaString,.rdpparaDp) para converter perfeitamente os tipos padrão do Kotlin e do Remote Compose. - Analise o exemplo de código:para conferir exemplos abrangentes de como criar layouts, aplicar tipografia semântica e gerenciar o estado no Remote Compose, consulte o exemplo de código oficial disponível no repositório de exemplos do Wear OS.