Communitygithub.com

axewhyzed/agentic-skills

Guia abrangente e framework operacional para engenharia moderna Android e Mobile UI/UX. Use ao projetar, auditar, construir ou refatorar aplicativos Android (Jetpack Compose, Material 3), ergonomia móvel, padrões offline-first outbox, cache stale-while-revalidate, ações inteligentes com um toque, integrações com framework de armazenamento, háptica tátil, transições de elementos compartilhados, gestos de voltar preditivos e autenticação móvel sem atritos.

O que é agentic-skills?

Este skill é um guia prático e testado em produção para construção de aplicativos Android nativos com Jetpack Compose e Material 3, com foco em resiliência offline-first e ergonomia centrada no ser humano. Ele codifica princípios de design de interface para dispositivos móveis — como a hierarquia de zonas de alcance do polegar, padrões mínimos de alvos de toque (48x48dp) e o layout de controles na metade inferior da tela — garantindo usabilidade real com uma mão. O skill descreve estratégias de desempenho percebido, como a 'Regra Zero-Skeleton' (stale-while-revalidate) e o padrão Offline-First Outbox, que usam armazenamento local (Room, EncryptedSharedPreferences) e WorkManager para fornecer feedback instantâneo ao usuário e envio em segundo plano com backoff exponencial. Ele também abrange transições de elementos compartilhados (SharedTransitionLayout), gestos de voltar preditivos (PredictiveBackHandler), háptica tátil para ações de milestone e física de mola para animações suaves e responsivas. Por fim, oferece diretrizes para autenticação móvel sem atritos, ações inteligentes sensíveis ao contexto (abrir URL, copiar texto, baixar arquivo), layouts adaptáveis para dobráveis e tablets usando WindowSizeClass, e acessibilidade de contraste WCAG 2.2 AA/AAA com correções específicas para armadilhas do Material 3 Dark Mode.

Funciona com~Claude Code~Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/axewhyzed/agentic-skills/tree/HEAD/.agents/skills/android-mobile-ui-ux

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Guia de Engenharia Android e Mobile UI/UX

Um framework operacional prático e testado em produção para projetar e construir aplicativos Android nativos com Jetpack Compose, Material 3, resiliência offline-first e ergonomia móvel centrada no ser humano.


1. Ergonomia Móvel Principal e Zona do Polegar

Dispositivos móveis são segurados com uma mão mais de 70% do tempo. Projete interfaces considerando o alcance do polegar, feedback tátil e atrito físico mínimo.

1.1 A Hierarquia de Alcance Ergonômico

+---------------------------+  <- Topo da Tela (Apenas Exibição)
|  Status e Cabeçalhos      |     Mais difícil de alcançar. Reserve para status
|  Título, Medidor de Cota  |     passivo, barras de busca e medidores ativos.
+---------------------------+
|                           |  <- Zona de Alcance Médio
|  Conteúdo Rolável         |     Ideal para itens de lista, detalhes e
|  Cartões de Caixa de Entrada, Trechos |     cartões de conteúdo navegável.
|                           |
+---------------------------+
|  Alvos de Ação Principal  |  <- Zona Principal do Polegar (40% Inferior)
|  Botões de Envio, Abas    |     Mais fácil de tocar. Mantenha navegação, CTAs
|  Folhas Inferiores, Filtros |     e controles interativos aqui.
+---------------------------+

1.2 Padrões Inegociáveis de Alvos de Toque

  • Alvo Interativo Mínimo: Cada elemento clicável deve atender ou exceder $48 \times 48\text{dp}$ (Modifier.sizeIn(minWidth = 48.dp, minHeight = 48.dp)), mesmo que o ícone visual seja $24\text{dp}$.
  • Insetos de Borda e Áreas Seguras: Sempre envolva layouts raiz do Compose em Scaffold ou aplique Modifier.windowInsetsPadding(WindowInsets.safeDrawing) para considerar recortes de câmera, gestos e barras de navegação.
  • Controles de Formulário na Parte Inferior: Coloque entradas de texto, botões de envio e diálogos de confirmação em ModalBottomSheet ou cartões fixados na parte inferior para que o teclado virtual (imePadding()) não obscureça o campo ativo.

2. Velocidade e Performance Percebida

Usuários móveis percebem atraso imediatamente. Nunca bloqueie a navegação ou mostre estados de carregamento vazios quando dados buscados anteriormente estiverem disponíveis.

2.1 A Regra Zero-Skeleton (Stale-While-Revalidate)

  • O Problema: Mostrar um esqueleto de carregamento de tela cheia ou um spinner circular toda vez que o usuário toca na aba da Caixa de Entrada parece lento, chocante e sem polimento.
  • A Solução: Implemente um padrão de cache Stale-While-Revalidate (SWR):
    1. Armazene itens buscados em armazenamento local criptografado (EncryptedSharedPreferences ou SQLite/Room).
    2. Ao entrar na tela, renderize itens em cache imediatamente (atraso 0ms).
    3. Revalide em segundo plano se o cache for mais antigo que 5–10 minutos.
    4. Quando os dados atualizados chegarem, anexe/atualize itens suavemente sem limpar a lista ou mostrar placeholders vazios.
    5. Mostre apenas indicadores sutis (ex.: um spinner de pull-to-refresh ou uma pequena barra de progresso no topo) durante atualizações em segundo plano.

2.2 Padrão Offline-First Outbox

Nunca falhe uma ação do usuário porque o dispositivo móvel tem uma conexão celular instável ou está temporariamente no modo avião.

flowchart TD
    UserAction["Usuário Compartilha Arquivo / Digita Nota"] --> LocalDraft["1. Salvar em Rascunhos Locais Outbox"]
    LocalDraft --> RenderOutbox["2. Renderizar no Cartão da Fila Outbox Imediatamente"]
    RenderOutbox --> CheckNet{"Conectado à Rede?"}
    CheckNet -- Sim --> DirectUpload["3. Enviar Diretamente"]
    CheckNet -- Não --> EnqueueWork["3. Enfileirar Trabalho WorkManager (NetworkType.CONNECTED)"]
    EnqueueWork --> WaitConn["4. Aguardar Wi-Fi / Celular"]
    WaitConn --> AutoDispatch["5. Envio em Segundo Plano com Backoff Exponencial"]
    DirectUpload --> Success["6. Atualizar Estado da UI & Notificar Toast"]
    AutoDispatch --> Success

Estados de UI do Outbox:

  • Pendente: "Aguardando rede…" com um ícone de nuvem pausada.
  • Enviando: "Enviando 42%…" com um indicador de progresso linear.
  • Falhou / Tentando Novamente: Indicador de status claro com botões explícitos Tentar Novamente e Descartar.

3. Movimento, Transições e Háptica Tátil

O design moderno do Android (Android 14/15+) requer movimento dinâmico baseado em física e feedback sensorial tátil para parecer nativo e responsivo.

3.1 Manipulação de Borda a Borda e Barras do Sistema

Sempre desenhe atrás das barras do sistema globalmente em MainActivity.kt:

enableEdgeToEdge()
setContent {
    VaultTheme {
        Scaffold(
            contentWindowInsets = WindowInsets.safeDrawing
        ) { innerPadding ->
            AppNavHost(Modifier.padding(innerPadding))
        }
    }
}

3.2 Gestos de Voltar Preditivos

Habilite a volta preditiva em AndroidManifest.xml (android:enableOnBackInvokedCallback="true") e use PredictiveBackHandler para folhas inferiores e gavetas de detalhes:

PredictiveBackHandler(enabled = isDetailOpen) { progressFlow ->
    try {
        progressFlow.collect { backEvent ->
            // Escala ou desloca a folha de detalhes proporcional a backEvent.progress (0f até 1f)
            detailScale = 1f - (backEvent.progress * 0.1f)
        }
        // Usuário confirmou o gesto de voltar
        closeDetail()
    } catch (e: CancellationException) {
        // Usuário abortou o gesto de voltar, retorna suavemente para 1f
        detailScale = 1f
    }
}

3.3 Transições de Elementos Compartilhados

Ao transitar entre uma linha de lista da Caixa de Entrada e uma visualização de detalhes do item, envolva as telas em SharedTransitionLayout:

SharedTransitionLayout {
    NavHost(...) {
        composable("inbox") {
            InboxScreen(
                sharedTransitionScope = this@SharedTransitionLayout,
                animatedVisibilityScope = this
            )
        }
        composable("detail/{id}") {
            DetailScreen(
                sharedTransitionScope = this@SharedTransitionLayout,
                animatedVisibilityScope = this
            )
        }
    }
}

Use .sharedElement() ou .sharedBounds() em cartões de miniatura, ícones de avatar e títulos para criar transições contínuas.

3.4 Háptica Tátil

Nunca deixe ações do usuário silenciosas quando um marco físico ocorrer:

  • Deslizes de Limiar (Swipe-to-Dismiss): Dispare HapticFeedbackConstantsCompat.GESTURE_START quando o deslize cruzar o limiar de ação.
  • Copiar para Área de Transferência / Envio Concluído: Dispare HapticFeedbackConstantsCompat.CONFIRM.
  • Falha de Validação / Erro de Rede: Dispare HapticFeedbackConstantsCompat.REJECT.
val view = LocalView.current
fun triggerHaptic(feedbackConstant: Int) {
    view.performHapticFeedback(feedbackConstant)
}

3.5 Física de Mola sobre Easing Linear

Evite animações lineares rígidas. Sempre use física de mola para gestos, folhas e descartes:

val offsetAnim by animateFloatAsState(
    targetValue = targetOffset,
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioMediumBouncy,
        stiffness = Spring.StiffnessLow
    )
)

4. Ações Inteligentes com Um Toque e Integração com o Sistema

Interfaces móveis devem minimizar a carga cognitiva reconhecendo o tipo de payload e oferecendo a ação nativa do sistema mais relevante.

4.1 Matriz de Ações Sensíveis ao Contexto

Tipo de PayloadAção PrimáriaAção SecundáriaIntegração com o Sistema
URL / Link da WebAbrir no Navegador (Intent.ACTION_VIEW)Copiar LinkChrome Custom Tabs ou navegador padrão do sistema
Texto / TrechoCopiar TextoCompartilhar (Intent.ACTION_SEND)ClipboardManager do Android com Toast / Snackbar instantâneo
Arquivo / MídiaBaixar para PastaAbrir ArquivoStorage Access Framework (SAF) + FileProvider

4.2 Downloads Diretos de Arquivos com Diretório Padrão Personalizado

Solicitar ao usuário o seletor de arquivos do sistema toda vez que ele baixar um arquivo cria atrito desnecessário.

  1. Permita que o usuário selecione uma Pasta de Download Padrão uma vez em Configurações/Central usando ActivityResultContracts.OpenDocumentTree().
  2. Persista a permissão permanentemente:
    context.contentResolver.takePersistableUriPermission(
        treeUri,
        Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
    )
    
  3. Ao tocar em Download:
    • Se um diretório padrão estiver definido: Transmita bytes diretamente usando DocumentFile.createFile(), mostre o progresso ao vivo do byte e dispare um Toast nativo de conclusão ("document.pdf baixado para Vault").
    • Se nenhum padrão estiver definido: Recorra a ActivityResultContracts.CreateDocument().

4.3 Abertura Segura de Arquivos com FileProvider

Nunca use URIs inseguros file:// crus. Sempre delegue a visualização de arquivos para aplicativos Android nativos usando FileProvider:

<!-- res/xml/file_paths.xml -->
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cached_files" path="." />
</paths>
val contentUri = FileProvider.getUriForFile(
    context,
    "${context.packageName}.fileprovider",
    tempFile
)
val intent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(contentUri, mimeType)
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(Intent.createChooser(intent, "Abrir com..."))

5. Autenticação Móvel Sem Atrito

Digitar URLs de servidor e senhas longas em telas sensíveis ao toque é propenso a erros de digitação.

5.1 Hierarquia de Prioridade de Login

  1. Prioridade 1: Leitura de Código QR com Câmera (Emparelhamento de 1 Segundo)
    • Exiba um código QR de emparelhamento temporário e assinado no aplicativo web para desktop.
    • O usuário móvel abre o aplicativo, toca em Ler Código QR e aponta a câmera para a tela.
    • O aplicativo analisa origem, token e nome do dispositivo em uma única passagem—autenticado instantaneamente.
  2. Prioridade 2: Nome de Usuário e Senha com URL do Servidor Recolhível
    • 99% dos logins usam o host configurado padrão.
    • Apresente apenas os campos Nome de Usuário e Senha por padrão.
    • Oculte a URL do servidor atrás de uma alternância recolhível sutil: "Configuração do servidor (avançado)".

5.2 Persistência de Sessão Deslizante de 14 Dias

  • Armazene tokens de acesso (va1_) e atualização (vr1_) no EncryptedSharedPreferences do Android.
  • Deslize/rote automaticamente o token de atualização em uso ativo.
  • Enquanto o usuário abrir o aplicativo dentro de 14 dias, ele permanecerá logado sem precisar se autenticar novamente.

6. Layouts Adaptáveis (Dobráveis e Tablets)

Construa telas que escalam suavemente entre classes de tamanho de janela usando WindowSizeClass:

  • Compact (<600dp): Coluna única, barra de navegação inferior, folhas inferiores modais.
  • Medium (600dp - 840dp): Trilho de navegação, grade de duas colunas.
  • Expanded (>840dp): Layout persistente de mestre-detalhe em dois painéis lado a lado (Lista à esquerda, inspetor à direita).

7. Contraste de Cor e Acessibilidade de Estado do Material 3 (WCAG 2.2 AA / AAA)

Dispositivos móveis são particularmente propensos a falhas de contraste devido à iluminação ambiente variável (luz solar direta, ofuscamento externo, escurecimento para economia de bateria OLED). Busque contraste de texto WCAG 2.2 AAA ($\ge 7:1$) e conformidade estrita com WCAG 1.4.11 (contraste de borda não texto $\ge 3:1$) e WCAG 1.4.1 (uso de cor).

7.1 A Armadilha do FilterChip do Material 3 em Modo Escuro

  • O Defeito: Por padrão, o FilterChip do Material 3 em modo escuro usa secondaryContainer (#37474F) como fundo selecionado contra a surface escura (#14181E). Isso produz uma taxa de contraste inaceitável de 1,83:1. Em baixo brilho ou ofuscamento, os usuários não conseguem distinguir qual chip está ativo.
  • A Correção:
    1. Imponha definição de borda de alto contraste com selectedBorderColor = MaterialTheme.colorScheme.primary (que produz uma taxa de contraste de 9,88:1 em modo escuro).
    2. Defina selectedBorderWidth = 1.5.dp.
    3. Cumpra WCAG 1.4.1 (estados não dependentes apenas de cor) fornecendo um ícone de marca de seleção principal:
      FilterChip(
          selected = isSelected,
          onClick = { onSelect() },
          label = { Text(label) },
          leadingIcon = if (isSelected) {
              { Icon(Icons.Filled.Done, contentDescription = null, Modifier.size(16.dp)) }
          } else null,
          border = FilterChipDefaults.filterChipBorder(
              enabled = true,
              selected = isSelected,
              selectedBorderColor = MaterialTheme.colorScheme.primary,
              selectedBorderWidth = 1.5.dp
          )
      )
      

7.2 Padrões de Legibilidade sob Luz Solar e Ofuscamento

  1. Texto Primário vs Superfície: Padronize o modo escuro com texto de alto contraste (onSurface #E1E2E8 ou #F8FAFC em #14181E), alcançando $\ge 13:1$ de contraste (excedendo WCAG AAA).
  2. Contornos de Controles de Formulário: OutlinedTextField e bordas de rádio/checkbox devem usar tokens outline que mantenham pelo menos $3:1$ de contraste contra cartões de contêiner (Color(0xFF8D9199) ou rgba(255, 255, 255, 0.20) explícito).
  3. Linhas de Preset Compacto: Ao dispor linhas de chips compactos (ex.: presets de retenção 1h, 4h, 12h, 1d), preserve tamanhos de alvo e aplique maxLines = 1 com selectedBorderColor para que os chips nunca quebrem ou pareçam ambíguos.

8. Repositórios de Código Aberto de Referência

Inspecione estes projetos Android de código aberto líderes do setor para inspiração de design e implementação:

  • android/nowinandroid: Amostra emblemática do Google de Material 3 Compose demonstrando temas dinâmicos, layouts adaptáveis e arquitetura limpa.
  • skydoves/Pokedex-Compose: Transições de elementos compartilhados de nível de produção (.sharedBounds / .sharedElement) e gestos suaves de folha de detalhes.
  • plainhub/plain-app: Implementação notável de gerenciamento local de telefone, temas Material You e sincronização responsiva cliente-servidor.
  • Gurupreet/ComposeCookBook: Catálogo exaustivo de animações de produção do Compose, barras inferiores e micro-interações de canvas personalizado.
  • signalapp/Signal-Android: Padrão ouro para armazenamento local criptografado, workers de outbox em segundo plano e resiliência de rede.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Habilidades Relacionadas