A Media3 fornece um PlayerView
padrão com algumas
opções de personalização. Para qualquer outra personalização, os desenvolvedores de apps
precisam implementar os próprios componentes de interface.
Práticas recomendadas
Ao implementar uma interface de mídia que se conecta a um Player
da Media3 (por exemplo,
ExoPlayer
, MediaController
ou uma implementação personalizada de Player
), aconselhamos os apps a seguir estas práticas recomendadas para ter a melhor experiência da interface.
Botão "Reproduzir/pausar"
O botão para reproduzir e pausar não corresponde diretamente a um único estado de player. Por exemplo, o usuário precisa conseguir reiniciar a reprodução depois que ela terminar ou falhar, mesmo que o player não esteja pausado.
Para simplificar a implementação, a Media3 oferece métodos utilitários para decidir qual
botão mostrar (Util.shouldShowPlayButton
) e processar os pressionamentos de botão
(Util.handlePlayPauseButtonAction
):
Kotlin
val shouldShowPlayButton: Boolean = Util.shouldShowPlayButton(player) playPauseButton.setImageDrawable(if (shouldShowPlayButton) playDrawable else pauseDrawable) playPauseButton.setOnClickListener { Util.handlePlayPauseButtonAction(player) }
Java
boolean shouldShowPlayButton = Util.shouldShowPlayButton(player); playPauseButton.setImageDrawable(shouldShowPlayButton ? playDrawable : pauseDrawable); playPauseButton.setOnClickListener(view -> Util.handlePlayPauseButtonAction(player));
Detectar atualizações de estado
O componente de interface precisa adicionar um Player.Listener
para ser informado sobre mudanças
de estado que exigem uma atualização de interface correspondente. Consulte
Ouvir eventos de reprodução para mais detalhes.
A atualização da interface pode ser cara, e vários eventos de jogadores geralmente chegam
juntos. Para evitar a atualização da interface com muita frequência em um curto período, geralmente é
melhor detectar apenas onEvents
e acionar atualizações da interface:
Kotlin
player.addListener(object : Player.Listener{ override fun onEvents(player: Player, events: Player.Events){ if (events.containsAny( Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_PLAYBACK_STATE_CHANGED, Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) { updatePlayPauseButton() } if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) { updateRepeatModeButton() } } })
Java
player.addListener(new Player.Listener() { @Override public void onEvents(Player player, Player.Events events) { if (events.containsAny( Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_PLAYBACK_STATE_CHANGED, Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) { updatePlayPauseButton(); } if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) { updateRepeatModeButton(); } } });
Gerenciar comandos disponíveis
Um componente de interface de uso geral que pode precisar trabalhar com diferentes implementações de Player
precisa verificar os comandos disponíveis do player para mostrar ou ocultar botões e evitar chamar métodos sem suporte:
Kotlin
nextButton.isEnabled = player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT)
Java
nextButton.setEnabled(player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT));