Partilhar: Classroom Teams WhatsApp
aulify · Sebenta
UC · Unidade de Competência · UC02210

Criar e desenvolver conteúdos, animações e aplicações multimédia para dispositivos móveis (UC02210)

Do contexto móvel à publicação: interfaces, interatividade, desempenho, PWA e acessibilidade
25h · 2.25 pontos crédito Curso: T. Multimédia, T. Audiovisuais, T. Produção de Conteúdos Interativos ↗ Referencial oficial SNQ
Índice

Há um pacote premium desta unidade: um PowerPoint editável de 100 ou mais diapositivos, um manual em PDF e dois testes com correção. Esta sebenta continua gratuita.

Introdução

Mais de metade do tráfego web mundial já vem de telemóveis. Um site ou uma aplicação que funcione bem num computador de secretária e mal num telemóvel perde a maioria dos seus utilizadores logo nos primeiros segundos. Esta sebenta ensina a criar, desenvolver e testar conteúdos, animações e aplicações multimédia pensados de raiz para dispositivos móveis, e não a "encolher" um site de desktop.

O percurso segue o trabalho real de quem desenvolve para móvel: primeiro entender o que distingue o contexto móvel do desktop; depois escolher a abordagem de desenvolvimento certa para cada projeto (nativa, híbrida, web app ou PWA); configurar a ferramenta de desenvolvimento; desenhar uma interface usável para dedos, não para ratos; construir um layout adaptativo; programar gestos e interatividade; animar com atenção ao desempenho e à acessibilidade; medir e otimizar com as métricas reais da web; transformar o projeto numa PWA que funciona offline; garantir acessibilidade; testar em dispositivo real; e por fim exportar e publicar.

Objetivos de aprendizagem (referencial): configurar e parametrizar a ferramenta de desenvolvimento de plataformas móveis; desenvolver conteúdos, animações e aplicações multimédia para dispositivos móveis; programar as aplicações multimédia e a interatividade; testar a navegação e a compatibilidade; e exportar e publicar aplicações.

1. O contexto móvel: o que distingue do desktop

Desenhar para móvel não é redimensionar um site de computador. O contexto de uso é radicalmente diferente e cada diferença tem consequências diretas no desenho e na programação.

Dimensão Desktop Móvel
Entrada rato e teclado, apontar com precisão dedo, área de contacto imprecisa
Ecrã grande, muitas vezes fixo pequeno, retrato ou paisagem, várias densidades
Rede cabo ou wi-fi estável 3G, 4G, 5G, wi-fi instável, variável
Energia ligado à corrente bateria limitada
Contexto sentado, atenção dedicada em movimento, uma mão, distraído
Sensores raros GPS, acelerómetro, câmara, microfone
Interrupções poucas chamadas, notificações, outras apps

Consequências práticas: os alvos de toque têm de ser maiores do que o cursor de um rato; o texto tem de ser legível sem dar zoom; as imagens e o código têm de pesar pouco, porque a rede é variável e cara; as animações têm de correr suavemente numa bateria limitada; e a interface tem de assumir que o utilizador usa uma mão só, muitas vezes em movimento.

Este é o fio condutor de toda a unidade: cada decisão de desenho e de código responde a uma destas diferenças.

2. Abordagens de desenvolvimento: nativa, híbrida, web app e PWA

Antes de desenhar seja o que for, decide-se como a aplicação vai chegar ao utilizador. Há quatro caminhos, com compromissos diferentes.

Quando escolher cada uma

Situação Abordagem recomendada
Jogo com gráficos 3D exigentes Nativa
App que usa muito a câmara, sensores ou pagamentos complexos Nativa ou híbrida
Equipa pequena, orçamento limitado, várias plataformas Híbrida ou PWA
Conteúdo informativo, catálogo, blog, formulário Web app ou PWA
Precisa de funcionar offline e ter ícone no ecrã, sem loja PWA

Exemplo resolvido · escolher a abordagem para um caso real

Uma escola de música quer uma aplicação para os alunos consultarem o horário das aulas, marcarem salas de ensaio e receberem um aviso quando uma aula for cancelada, mesmo com pouca rede no bairro. Não precisa de câmara nem de sensores avançados, e o orçamento é limitado.

Resolução: a escolha certa é uma PWA. Não justifica o custo de duas apps nativas; precisa de funcionar com rede fraca (o service worker resolve isso); precisa de avisos (as notificações push de uma PWA chegam); e o aluno pode instalá-la a partir do browser, sem passar pela loja.

3. Configurar e parametrizar a ferramenta de desenvolvimento

Antes de escrever a primeira linha, configura-se o ambiente de trabalho de plataformas móveis.

<meta name="viewport" content="width=device-width, initial-scale=1">

Exemplo resolvido · ativar o modo de dispositivo no Chrome DevTools

  1. Abrir a página no Chrome, premir F12 (ou Cmd+Option+I no Mac).
  2. Clicar no ícone de telemóvel/tablet no canto superior esquerdo do painel (Toggle device toolbar).
  3. Escolher um dispositivo da lista (ex.: iPhone 14, Pixel 7) ou definir uma resolução personalizada.
  4. No menu de rede, escolher "Slow 3G" para simular a rede móvel real.
  5. Recarregar a página e observar o que muda: layout, tamanho de texto, tempo de carregamento.

Sem a meta viewport, este passo mostraria a página encolhida a fingir ser um ecrã de 980px, o erro mais comum de quem começa em desenvolvimento móvel.

4. Usabilidade e desenho de interface móvel

A usabilidade assenta em quatro princípios: feedback ao utilizador (a interface responde de imediato a cada toque), eficiência (poucos passos até ao objetivo), consistência (os mesmos gestos fazem sempre a mesma coisa) e facilidade de aprendizagem (usa-se sem manual).

A zona do polegar

A maioria dos utilizadores segura o telemóvel com uma mão e navega com o polegar. O ecrã divide-se em zonas de alcance:

Regra prática: ações frequentes e importantes vão na zona fácil (navegação principal, botão de ação primária); informação de leitura e ações raras podem ir mais acima.

Área mínima de toque

Um dedo não é um cursor de rato. A área mínima recomendada para qualquer elemento tocável é 44×44 pontos no iOS e 48×48dp no Android, com espaço à volta para não tocar no botão errado. Um botão de 20px de altura pode parecer bem desenhado num ecrã de computador e ser impossível de tocar num telemóvel.

Hierarquia visual e navegação

Exemplo resolvido · corrigir um botão fora da área mínima

Um botão de "Confirmar" tem width: 60px; height: 24px; e está a meio de uma lista de campos de formulário, colado a um botão de "Cancelar" igual, sem espaço entre eles.

Resolução: aumentar para min-height: 48px; min-width: 96px;, adicionar padding: 12px 24px; para a área de toque crescer sem depender só do texto, e afastar os dois botões com gap: 16px;. Colocar "Confirmar" na zona fácil (fundo do ecrã) e "Cancelar" ao lado, mas menos destacado, para reduzir toques acidentais.

5. A viewport e o desenho adaptativo

O design responsivo adapta o mesmo conteúdo a diferentes tamanhos de ecrã, do telemóvel ao ecrã de alta resolução, sem duplicar código.

Media queries

As media queries aplicam regras CSS só a partir de certas condições, tipicamente a largura do ecrã:

/* base: estilos para o telemóvel */
.cartao { flex-direction: column; }

/* a partir de 768px (tablet) */
@media (min-width: 768px) {
  .cartao { flex-direction: row; }
}

/* a partir de 1024px (desktop) */
@media (min-width: 1024px) {
  .cartao { max-width: 960px; margin: 0 auto; }
}

A boa prática é mobile-first: escrever primeiro o estilo do ecrã pequeno e ir acrescentando regras para ecrãs maiores com min-width, em vez do inverso.

Unidades relativas

Usar unidades relativas em vez de pixels fixos permite que o layout se adapte ao tamanho de letra e ao ecrã do utilizador:

Unidade Relativa a Uso típico
rem tamanho de letra da raiz (html) espaçamentos, tamanhos de fonte
em tamanho de letra do elemento pai espaçamentos dentro de um componente
% dimensão do elemento pai larguras de contentores
vw / vh largura/altura da janela elementos a ecrã inteiro

Imagens adaptativas

O srcset e o sizes deixam o browser escolher a imagem certa para o ecrã e a densidade do utilizador, sem transferir mais dados do que precisa:

<img src="hero-800.jpg"
     srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
     sizes="(max-width: 600px) 100vw, 50vw"
     alt="Capa do evento de música ao vivo">

O elemento <picture> vai mais longe: permite servir formatos diferentes (WebP para quem suporta, JPEG como alternativa) consoante o dispositivo.

Exemplo resolvido · breakpoint com imagem adaptativa

Uma página de catálogo mostra uma imagem grande de topo (hero) e uma grelha de produtos. No telemóvel, a grelha deve ter 1 coluna; no tablet, 2; no desktop, 4.

.grelha { display: grid; grid-template-columns: 1fr; gap: 1rem; }

@media (min-width: 600px) {
  .grelha { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .grelha { grid-template-columns: repeat(4, 1fr); }
}

A imagem de topo usa srcset com três larguras, para o telemóvel nunca transferir a versão de 1200px pensada para o desktop.

6. Gestos, estados de toque e interatividade programada

Esta é a realização central de programar a aplicação, não apenas desenhá-la: transformar um layout estático numa interface que responde ao toque.

Gestos comuns

Estados de toque

Cada elemento interativo deve ter estados visuais claros, porque não há cursor a passar por cima a avisar que algo é clicável:

.botao { transition: transform 0.1s, background-color 0.1s; }
.botao:active { transform: scale(0.97); background-color: var(--cor-primaria-escura); }
.botao:focus-visible { outline: 3px solid var(--cor-foco); outline-offset: 2px; }
.botao:disabled { opacity: 0.5; pointer-events: none; }

Programar a interatividade com JavaScript

Os eventos de toque (touchstart, touchmove, touchend) e, de forma mais moderna e unificada, os Pointer Events (pointerdown, pointermove, pointerup), permitem programar gestos personalizados que não existem em CSS puro.

Exemplo resolvido · carrossel de imagens com swipe

Programar um carrossel simples que avança de imagem com um gesto de deslizar horizontal:

const carrossel = document.querySelector('.carrossel');
let inicioX = 0;

carrossel.addEventListener('touchstart', (evento) => {
  inicioX = evento.touches[0].clientX;
});

carrossel.addEventListener('touchend', (evento) => {
  const fimX = evento.changedTouches[0].clientX;
  const distancia = fimX - inicioX;

  if (Math.abs(distancia) > 50) {   // limiar mínimo para contar como swipe
    if (distancia < 0) {
      avancarImagem();
    } else {
      recuarImagem();
    }
  }
});

O limiar de 50 pixels evita que um pequeno tremor do dedo dispare o gesto por engano. É esta lógica, entre o desenho da interface e o código que a torna viva, que separa uma aplicação multimédia interativa de um simples documento a ser lido.

7. Animação e movimento com atenção à acessibilidade

A animação orienta a atenção, dá feedback e torna a interface mais agradável, mas em móvel tem um custo real: bateria e desempenho.

Como animar bem

.cartao-entrada {
  transform: translateY(20px);
  opacity: 0;
  transition: transform 0.3s ease-out, opacity 0.3s ease-out;
}
.cartao-entrada.visivel {
  transform: translateY(0);
  opacity: 1;
}

Respeitar quem não quer movimento

Algumas pessoas têm perturbações vestibulares ou de atenção a quem o movimento no ecrã causa tonturas ou desconforto real. O sistema operativo tem uma definição de acessibilidade para "reduzir a moção", que o CSS pode ler:

@media (prefers-reduced-motion: reduce) {
  .cartao-entrada {
    transition: none;
    transform: none;
    opacity: 1;
  }
}

Com esta media query, quem ativou "reduzir movimento" nas definições do telemóvel recebe a interface pronta, sem a animação de entrada, mas continua a ver e a usar tudo.

Exemplo resolvido · aplicar prefers-reduced-motion a um carrossel automático

Um carrossel de imagens na página inicial muda de imagem automaticamente a cada 4 segundos, com um efeito de deslizamento.

Resolução: envolver o avanço automático numa verificação em JavaScript e desligar a transição em CSS:

const prefereMenosMovimento = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

if (!prefereMenosMovimento) {
  setInterval(avancarCarrossel, 4000);
}
@media (prefers-reduced-motion: reduce) {
  .carrossel-slide { transition: none; }
}

O carrossel continua a mostrar as imagens (por clique manual, por exemplo), mas deixa de as trocar sozinho com movimento, respeitando a escolha do utilizador.

8. Desempenho e as métricas reais da web

"Parece rápido" não chega. A Google definiu três métricas objetivas, os Core Web Vitals, que medem a experiência real de quem usa o site, sobretudo em rede móvel.

Métrica Mede Bom A melhorar Mau
LCP (Largest Contentful Paint) tempo até o maior elemento visível aparecer até 2,5s até 4s acima de 4s
CLS (Cumulative Layout Shift) quanto o layout "salta" enquanto carrega até 0,1 até 0,25 acima de 0,25
INP (Interaction to Next Paint) tempo entre um toque e a resposta visual até 200ms até 500ms acima de 500ms

O que degrada estas métricas em rede móvel

Em rede móvel, tudo isto agrava-se: a latência de uma rede 4G é muito maior do que a de um wi-fi de escritório, e cada pedido extra ao servidor custa tempo real.

Exemplo resolvido · diagnosticar e corrigir um LCP alto

O Lighthouse (integrado nas DevTools do Chrome, gratuito) reporta um LCP de 5,8 segundos numa página de destino, com a imagem de fundo do cabeçalho identificada como o elemento LCP.

Resolução:

  1. Confirmar no separador Network que a imagem pesa 2,4 MB, um ficheiro PNG sem compressão.
  2. Converter para WebP e comprimir (ver capítulo 9), reduzindo para cerca de 180 KB.
  3. Adicionar <link rel="preload" as="image" href="hero.webp"> no <head>, para o browser começar a descarregá-la mais cedo.
  4. Repetir a medição no Lighthouse: LCP desce para 2,1 segundos, dentro da faixa "bom".

9. Otimização de imagens e de tipos de letra

As imagens e os tipos de letra são, tipicamente, o maior peso de uma página. Otimizá-los é a forma mais eficaz de melhorar o desempenho em rede móvel.

Imagens

<img src="produto.webp" loading="lazy" width="400" height="300" alt="Colar artesanal em prata">

Os atributos width e height no HTML reservam o espaço antes de a imagem carregar, o que reduz diretamente o CLS.

Tipos de letra

@font-face {
  font-family: 'Marca';
  src: url('marca-variable.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-display: swap;
}

10. PWA: manifest, service worker e funcionamento offline

Uma Progressive Web App transforma uma web app numa aplicação instalável e resiliente, sem sair de HTML, CSS e JavaScript.

O ficheiro manifest.json

Descreve a aplicação para o sistema operativo poder instalá-la:

{
  "name": "Horário da Escola de Música",
  "short_name": "Horário",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#1a1e5d",
  "icons": [
    { "src": "icone-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "icone-512.png", "sizes": "512x512", "type": "image/png" }
  ]
}

O service worker

É um script que corre em segundo plano, entre a aplicação e a rede, e que sobrevive mesmo com a aba fechada. Tem um ciclo de vida próprio:

  1. install: regista o service worker e pode pré-guardar os ficheiros essenciais em cache.
  2. activate: limpa caches antigas de versões anteriores.
  3. fetch: intercepta cada pedido de rede e decide se responde a partir da cache ou vai buscar à rede.

Estratégias de cache

Estratégia Como funciona Usa-se para
Cache first tenta a cache; só vai à rede se faltar ícones, tipos de letra, ficheiros estáticos
Network first tenta a rede; usa a cache se falhar conteúdo que muda (horário, preços)
Stale-while-revalidate responde da cache já, atualiza em segundo plano listas que podem ficar um pouco desatualizadas

Exemplo resolvido · service worker básico com cache first

const CACHE = 'horario-v1';
const FICHEIROS = ['/', '/estilo.css', '/app.js', '/icone-192.png'];

self.addEventListener('install', (evento) => {
  evento.waitUntil(
    caches.open(CACHE).then((cache) => cache.addAll(FICHEIROS))
  );
});

self.addEventListener('fetch', (evento) => {
  evento.respondWith(
    caches.match(evento.request).then((resposta) => resposta || fetch(evento.request))
  );
});

Com isto instalado, a aplicação abre mesmo sem rede: o ecrã principal, o estilo e o script vêm da cache. Para não escrever este código à mão em projetos maiores, a biblioteca gratuita Workbox (da Google) gera estas estratégias automaticamente.

11. Acessibilidade em dispositivos móveis

Uma aplicação acessível serve mais pessoas, incluindo quem tem baixa visão, daltonismo, dificuldades motoras ou usa um leitor de ecrã. Em móvel, o ecrã pequeno torna estes cuidados ainda mais decisivos.

Exemplo resolvido · corrigir um contraste insuficiente

Um botão de "Ver mais" está escrito a cinzento claro (#aaaaaa) sobre fundo branco, um rácio de cerca de 2,3:1, abaixo do mínimo.

Resolução: escurecer o texto para #5a5a5a (rácio acima de 4,5:1 sobre branco), confirmado no verificador de contraste, mantendo a mesma paleta visual da marca mas com legibilidade garantida para quem tem baixa visão.

12. Testar e depurar a navegação e a compatibilidade

Nenhuma aplicação está pronta sem ser testada fora do computador de quem a construiu.

Testar em dispositivo real

Os emuladores e simuladores são úteis, mas não substituem um telemóvel real: só ele mostra a velocidade de rede verdadeira, o comportamento do ecrã tátil, o consumo de bateria e as particularidades de cada fabricante.

Depuração remota (remote debugging)

Com a depuração remota, corrigem-se erros de JavaScript, inspeciona-se o CSS real aplicado e mede-se o desempenho tal como o utilizador o vive, não como o computador de desenvolvimento o simula.

Ferramentas de teste gratuitas

Checklist de compatibilidade

13. Exportar e publicar aplicações

A última etapa transforma o projeto testado num produto que chega ao utilizador final.

Publicar uma PWA

  1. Alojar em HTTPS obrigatoriamente: o service worker não regista em ligações inseguras.
  2. Verificar a instalabilidade no separador Application das DevTools do Chrome (secções Manifest e Service workers), que mostra se o manifest e o service worker cumprem os critérios de instalação. O Lighthouse (desempenho, acessibilidade, boas práticas e SEO) continua a servir para medir o LCP e o CLS, mas já não tem categoria de PWA.
  3. Testar o ícone de "Adicionar ao ecrã principal" em Android e em iOS.
  4. Opcionalmente, submeter a listagens como a PWA Builder (Microsoft, gratuita), que ajuda a empacotar a PWA também para as lojas de aplicações.

Publicar uma aplicação híbrida ou nativa

  1. Gerar o pacote de instalação: AAB (Android App Bundle) para a Play Store, IPA para a App Store.
  2. Assinar digitalmente o pacote com um certificado próprio do programador.
  3. Submeter na Play Console (Android) ou na App Store Connect (iOS), com capturas de ecrã, descrição e política de privacidade.
  4. Aguardar a revisão da loja: o Android é geralmente automático e rápido; a Apple faz revisão manual e pode pedir correções.

Checklist final antes de publicar

Erros comuns

Glossário

Síntese

Desenvolver para móvel começa por entender o contexto (toque, ecrã pequeno, rede variável, bateria limitada) e escolher a abordagem certa (nativa, híbrida, web app ou PWA). Sobre essa base, desenha-se uma interface usável para o polegar, com um layout adaptativo feito de media queries, unidades relativas e imagens adaptativas. Programa-se a interatividade com gestos e eventos de toque, e anima-se com transform e opacity, sempre a respeitar prefers-reduced-motion. Mede-se o resultado com as métricas reais da web, LCP, CLS e INP, e otimizam-se imagens e tipos de letra para pesarem pouco em rede móvel. Uma PWA acrescenta manifest, service worker e funcionamento offline. Garante-se acessibilidade de contraste, texto, leitores de ecrã e foco visível, testa-se em dispositivo real com depuração remota, e só então se exporta e publica a aplicação.

Exercícios resolvidos

1. Um cliente pede uma aplicação de meditação guiada com áudio, que precisa de funcionar offline e não tem orçamento para duas equipas de desenvolvimento nativo. Que abordagem recomendas e porquê?

Resolução: uma PWA. Cobre o requisito de funcionar offline através do service worker, não exige duas equipas nativas, permite instalação no ecrã principal, e é suficiente para reproduzir áudio e mostrar conteúdo, sem precisar do acesso profundo ao hardware que só o nativo oferece.

2. Uma página tem um LCP de 6,2 segundos. A imagem principal pesa 3 MB em PNG e não tem srcset. Descreve as correções, por ordem de impacto.

Resolução: primeiro, converter a imagem para WebP e comprimir com o Squoosh, o que costuma reduzir o peso em 80% ou mais; segundo, adicionar srcset com várias larguras, para o telemóvel não transferir a versão de desktop; terceiro, adicionar <link rel="preload"> para o browser começar a descarregar a imagem mais cedo. Estas três correções, isoladas ou juntas, costumam trazer o LCP para dentro da faixa "bom" (até 2,5s).

3. Um botão de like anima com left e top em JavaScript com setInterval, e engasga em telemóveis Android mais antigos. Corrige o código, em traços gerais.

Resolução: substituir a animação de left/top por transform: translate(...), que é acelerada pela GPU e não obriga a recalcular o layout; substituir setInterval por requestAnimationFrame, que sincroniza com o ecrã; e envolver a animação numa verificação de prefers-reduced-motion, para respeitar quem desativou o movimento.

4. Explica a diferença entre a estratégia de cache "cache first" e "network first" num service worker, e dá um exemplo de quando usar cada uma nesta UC.

Resolução: cache first responde sempre a partir da cache, só indo à rede se o ficheiro não existir lá; serve para ficheiros estáticos que quase nunca mudam, como ícones e tipos de letra. Network first tenta sempre a rede primeiro, e só usa a cache se a rede falhar; serve para conteúdo que muda, como o horário das aulas do exemplo do capítulo 2, onde mostrar dados desatualizados sem tentar atualizar primeiro seria um erro.

5. Uma aplicação tem texto cinzento claro sobre fundo branco e desativou o zoom do utilizador. Identifica os dois problemas de acessibilidade e corrige-os.

Resolução: primeiro problema, contraste insuficiente: o texto deve cumprir o rácio mínimo de 4,5:1, verificável com o WebAIM Contrast Checker, e corrige-se escurecendo a cor do texto. Segundo problema, zoom desativado com user-scalable=no: deve remover-se essa restrição da meta viewport, porque impede utilizadores com baixa visão de ampliar o conteúdo, uma barreira de acessibilidade grave.