TV App — um aplicativo para smart TVs que funciona nas plataformas Apple TV (tvOS) e Android TV (Google TV). Ao contrário dos aplicativos móveis, o TV App é desenvolvido considerando a navegação com controle remoto, o gerenciamento de foco (Focus Engine) e os requisitos específicos de interface em uma tela grande. O desenvolvimento é feito em Swift/SwiftUI para Apple TV e em Kotlin com Leanback Library para Android TV. De acordo com a Statista (2026), mais de 250 milhões de dispositivos em todo o mundo funcionam nessas plataformas, tornando o TV App um nicho promissor para desenvolvedores. Vamos analisar a arquitetura das plataformas, o gerenciamento de foco, exemplos de código e o processo de publicação.
Principais pontos
TV App — um aplicativo projetado para funcionar em plataformas de smart TV: Apple TV (tvOS) e Android TV (Google TV). A principal diferença de um aplicativo móvel é o método de interação. O usuário não toca na tela, mas controla a interface usando um controle remoto. Todos os elementos devem ser acessíveis através de navegação direcional (D-pad): cima, baixo, esquerda, direita e botão de seleção.
Características do desenvolvimento de TV App: a resolução da tela varia de Full HD (1920x1080) a 4K (3840x2160) com densidade xhdpi (Android) ou @3x (Apple). Uma zona segura de 5% das bordas é obrigatória para compensar o over-scan (parte da imagem pode ser cortada pela TV). Não há tela sensível ao toque — todas as interações são via controle remoto ou gamepad. O foco sempre destaca o elemento ativo. O consumo de energia não é limitado pela bateria, mas o aplicativo deve lidar corretamente com a transição para o modo de suspensão. De acordo com a Statista (2026), o mercado global de smart TV ultrapassa 80% das novas TVs, com Apple TV e Android TV representando mais de 250 milhões de dispositivos.
Categorias de aplicativos TV: serviços de vídeo (Netflix, YouTube, Apple TV+), música (Spotify, Apple Music), jogos (Apple Arcade, Google Play Games), fitness (Apple Fitness+, Peloton), educação, notícias, clima, fotos. A categoria mais popular é streaming de vídeo, que ocupa 70% de todo o tempo de uso de smart TV.
tvOS é o sistema operacional da Apple para o Apple TV, baseado no iOS. O primeiro lançamento foi em 2015 juntamente com o Apple TV de 4ª geração. O tvOS compartilha com o iOS o kernel XNU, os frameworks Foundation, UIKit (em uma versão adaptada) e o mecanismo de segurança App Sandbox. O desenvolvimento é feito em Swift usando SwiftUI ou UIKit.
Componentes principais do tvOS:
O ciclo de vida de um aplicativo tvOS é semelhante ao iOS: notRunning, foregroundActive, foregroundInactive, background. Particularidade: o aplicativo não deve solicitar permissões em segundo plano desnecessariamente — o sistema pode encerrar à força um processo em segundo plano. A topologia de navegação é construída em torno de UISplitViewController e UITabBarController com guias "Início", "Buscar", "Biblioteca", "Configurações".
Android TV é uma versão do Android otimizada para TVs e decodificadores, apresentada pela primeira vez em 2014. Desde 2020, existe o Google TV — uma camada sobre o Android TV com uma nova interface, mas o desenvolvimento de aplicativos é feito no SDK do Android TV, compatível com Google TV. A linguagem principal é Kotlin, os frameworks de UI são Leanback Library (clássico) e Jetpack Compose for TV (experimental).
Componentes chave do Android TV:
Diferenças entre Android TV e Android móvel: o aplicativo deve declarar a categoria LEANBACK_LAUNCHER no manifesto; a largura mínima do layout é 1920dp; a interação por toque é substituída pela navegação com D-pad; recomenda-se o uso de fragmentos Leanback; a aceleração de hardware é obrigatória. O build inclui APK/AAB com suporte para arquiteturas ARM64 e x86. Para projetos modernos a partir de 2025, recomenda-se Jetpack Compose for TV com componentes TvLazyColumn, TvButton, TvCard.
Focus Engine é um componente chave de qualquer plataforma TV, responsável por determinar qual elemento da interface está ativo. No tvOS, o Focus Engine está integrado ao UIKit e funciona automaticamente. Quando um botão do D-pad é pressionado, o sistema analisa a posição de todos os elementos focáveis, calcula o candidato mais próximo na direção da pressão e move suavemente o foco para ele com animação (UIFocusAnimationCoordinator).
Regras do Focus Engine: o sistema considera a distância entre os elementos ao longo do eixo de movimento, a interseção das projeções dos elementos (um elemento é considerado candidato se sua projeção intersectar a projeção do foco atual), prioridade para elementos à mesma distância (o mais próximo em linha reta é selecionado). O desenvolvedor pode influenciar o foco usando UIFocusGuide — um retângulo guia invisível que redireciona o foco para um elemento específico ao pressionar em uma determinada direção.
No Android TV, o foco é implementado através do sistema de foco padrão do Android com atributos focusable e nextFocus* (nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight). A animação é configurada através de StateListAnimator. O Google recomenda definir focusable em todos os elementos interativos e usar nextFocus para controle preciso da navegação. A animação de foco é crítica para a experiência do usuário — ao mudar o foco, uma animação suave de escala (1.0 → 1.05–1.2) deve ocorrer com duração de 150–250 ms.
Exemplo de um aplicativo TV simples em SwiftUI para Apple TV exibindo uma lista de filmes com suporte ao Focus Engine.
import SwiftUI
struct Movie: Identifiable {
let id = UUID()
let title: String
let subtitle: String
}
struct ContentView: View {
@FocusState private var focusedMovie: UUID?
let movies: [Movie] = [
Movie(title: "Inception", subtitle: "2010, Sci-Fi"),
Movie(title: "Interstellar", subtitle: "2014, Sci-Fi"),
Movie(title: "The Matrix", subtitle: "1999, Action"),
Movie(title: "Blade Runner 2049", subtitle: "2017, Sci-Fi"),
]
var body: some View {
VStack(alignment: .leading, spacing: 40) {
Text("Filmes").font(.title).padding(.leading, 60)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 40) {
ForEach(movies) { movie in
VStack {
Image(systemName: "film.fill")
.resizable()
.frame(width: 200, height: 300)
.cornerRadius(12)
.focusable()
.focused($focusedMovie, equals: movie.id)
Text(movie.title).font(.headline)
Text(movie.subtitle).font(.subheadline).foregroundColor(.secondary)
}
.scaleEffect(focusedMovie == movie.id ? 1.15 : 1.0)
.animation(.easeInOut(duration: 0.2), value: focusedMovie)
}
}
.padding(.horizontal, 60)
}
}
.onAppear { focusedMovie = movies.first?.id }
}
}
Pontos chave: @FocusState — rastreamento do foco atual; .focusable() — torna um elemento focável; .scaleEffect() — animação de zoom ao focar, importante para feedback visual na TV.
Um exemplo semelhante para Android TV com Leanback Library em Kotlin:
// MainActivity.kt
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
class MainFragment : BrowseSupportFragment() {
private val moviePresenter = MoviePresenter()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
title = getString(R.string.app_name)
headersState = HEADERS_ENABLED
setupAdapter()
}
private fun setupAdapter() {
val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
val listRowAdapter = ArrayObjectAdapter(moviePresenter)
listRowAdapter.add(Movie("Inception", "2010", R.drawable.poster_1))
listRowAdapter.add(Movie("Interstellar", "2014", R.drawable.poster_2))
rowsAdapter.add(ListRow(HeaderItem(0, "Movies"), listRowAdapter))
adapter = rowsAdapter
}
}
data class Movie(val title: String, val subtitle: String, val imageResId: Int)
class MoviePresenter : Presenter() {
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
val cardView = ImageCardView(parent.context).apply {
isFocusable = true
setMainImageDimensions(200, 300)
}
return ViewHolder(cardView)
}
override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
val movie = item as Movie
(viewHolder.view as ImageCardView).apply {
titleText = movie.title
contentText = movie.subtitle
}
}
override fun onUnbindViewHolder(viewHolder: ViewHolder) {}
}
Pontos chave: BrowseSupportFragment — o fragmento principal do Leanback com cabeçalhos; Presenter — uma abstração para criar ViewHolder, similar a RecyclerView.Adapter; ImageCardView — cartão padrão com imagem, título e subtítulo; isFocusable = true — atributo obrigatório para elementos TV.
Perguntas frequentes
Um TV App é controlado por controle remoto (D-pad) em vez de toque, usa Focus Engine para navegação, é otimizado para tela grande (Full HD ou 4K) e não tem limitações de bateria. Todos os elementos devem ser acessíveis através do movimento direcional do foco.
O Focus Engine é um sistema no tvOS que determina automaticamente o elemento ativo da interface. Quando um botão do D-pad é pressionado, o sistema analisa a posição dos elementos focáveis, calcula o candidato mais próximo e move suavemente o foco para ele com animação.
O framework principal é Leanback Library (BrowseFragment, DetailsFragment, PlaybackOverlayFragment). Para projetos modernos, Jetpack Compose for TV também está disponível com suporte experimental.
Para o desenvolvimento inicial, simuladores são suficientes: o Xcode inclui o tvOS Simulator com Siri Remote, o Android Studio inclui o Android TV Emulator. Para testes finais, um dispositivo físico é recomendado.
O Apple TV App é publicado através do App Store Connect com Xcode Organizer. O Android TV App é publicado através do Google Play Console com LEANBACK_LAUNCHER declarado no manifesto e capturas de tela de 1920x1080.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também