Commit 195a93e5 by olly Committed by Oliver Woodman

Fix playback control focus

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=140623107
parent 8dc81040
......@@ -22,6 +22,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
......@@ -194,6 +195,16 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
}
}
// Activity input
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
// Show the controls on any key event.
simpleExoPlayerView.showController();
// If the event was not handled then see if the player view can handle it as a media key event.
return super.dispatchKeyEvent(event) || simpleExoPlayerView.dispatchMediaKeyEvent(event);
}
// OnClickListener methods
@Override
......
......@@ -16,13 +16,11 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
<com.google.android.exoplayer2.ui.SimpleExoPlayerView android:id="@+id/player_view"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
......
......@@ -236,6 +236,8 @@ public class PlaybackControlView extends FrameLayout {
componentListener = new ComponentListener();
LayoutInflater.from(context).inflate(controllerLayoutId, this);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
durationView = (TextView) findViewById(R.id.exo_duration);
positionView = (TextView) findViewById(R.id.exo_position);
progressBar = (SeekBar) findViewById(R.id.exo_progress);
......@@ -359,6 +361,7 @@ public class PlaybackControlView extends FrameLayout {
visibilityListener.onVisibilityChange(getVisibility());
}
updateAll();
requestPlayPauseFocus();
}
// Call hideAfterTimeout even if already visible to reset the timeout.
hideAfterTimeout();
......@@ -408,12 +411,18 @@ public class PlaybackControlView extends FrameLayout {
if (!isVisible() || !isAttachedToWindow) {
return;
}
boolean requestPlayPauseFocus = false;
boolean playing = player != null && player.getPlayWhenReady();
if (playButton != null) {
playButton.setVisibility(playing ? GONE : VISIBLE);
requestPlayPauseFocus |= playing && playButton.isFocused();
playButton.setVisibility(playing ? View.GONE : View.VISIBLE);
}
if (pauseButton != null) {
pauseButton.setVisibility(playing ? VISIBLE : GONE);
requestPlayPauseFocus |= !playing && pauseButton.isFocused();
pauseButton.setVisibility(!playing ? View.GONE : View.VISIBLE);
}
if (requestPlayPauseFocus) {
requestPlayPauseFocus();
}
}
......@@ -481,6 +490,15 @@ public class PlaybackControlView extends FrameLayout {
}
}
private void requestPlayPauseFocus() {
boolean playing = player != null && player.getPlayWhenReady();
if (!playing && playButton != null) {
playButton.requestFocus();
} else if (playing && pauseButton != null) {
pauseButton.requestFocus();
}
}
private void setButtonEnabled(boolean enabled, View view) {
if (view == null) {
return;
......@@ -590,40 +608,66 @@ public class PlaybackControlView extends FrameLayout {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (player == null || event.getAction() != KeyEvent.ACTION_DOWN) {
return super.dispatchKeyEvent(event);
}
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_DPAD_RIGHT:
fastForward();
break;
case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_DPAD_LEFT:
rewind();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
player.setPlayWhenReady(!player.getPlayWhenReady());
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
player.setPlayWhenReady(true);
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
player.setPlayWhenReady(false);
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
next();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
previous();
break;
default:
return false;
boolean handled = dispatchMediaKeyEvent(event) || super.dispatchKeyEvent(event);
if (handled) {
show();
}
return handled;
}
/**
* Called to process media key events. Any {@link KeyEvent} can be passed but only media key
* events will be handled.
*
* @param event A key event.
* @return Whether the key event was handled.
*/
public boolean dispatchMediaKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (player == null || !isHandledMediaKey(keyCode)) {
return false;
}
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
fastForward();
break;
case KeyEvent.KEYCODE_MEDIA_REWIND:
rewind();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
player.setPlayWhenReady(!player.getPlayWhenReady());
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
player.setPlayWhenReady(true);
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
player.setPlayWhenReady(false);
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
next();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
previous();
break;
default:
break;
}
}
show();
return true;
}
private static boolean isHandledMediaKey(int keyCode) {
return keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD
|| keyCode == KeyEvent.KEYCODE_MEDIA_REWIND
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY
|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE
|| keyCode == KeyEvent.KEYCODE_MEDIA_NEXT
|| keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS;
}
private final class ComponentListener implements ExoPlayer.EventListener,
SeekBar.OnSeekBarChangeListener, OnClickListener {
......
......@@ -216,6 +216,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
LayoutInflater.from(context).inflate(playerLayoutId, this);
componentListener = new ComponentListener();
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
// Content frame.
contentFrame = (AspectRatioFrameLayout) findViewById(R.id.exo_content_frame);
......@@ -377,6 +378,26 @@ public final class SimpleExoPlayerView extends FrameLayout {
}
/**
* Called to process media key events. Any {@link KeyEvent} can be passed but only media key
* events will be handled. Does nothing if playback controls are disabled.
*
* @param event A key event.
* @return Whether the key event was handled.
*/
public boolean dispatchMediaKeyEvent(KeyEvent event) {
return useController && controller.dispatchMediaKeyEvent(event);
}
/**
* Shows the playback controls. Does nothing if playback controls are disabled.
*/
public void showController() {
if (useController) {
maybeShowController(true);
}
}
/**
* Returns the playback controls timeout. The playback controls are automatically hidden after
* this duration of time has elapsed without user input and with playback or buffering in
* progress.
......@@ -473,11 +494,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
return true;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return useController ? controller.dispatchKeyEvent(event) : super.dispatchKeyEvent(event);
}
private void maybeShowController(boolean isForced) {
if (!useController || player == null) {
return;
......
......@@ -17,9 +17,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layoutDirection="ltr"
android:background="#CC000000"
android:orientation="vertical"
android:layoutDirection="ltr">
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
......@@ -69,6 +69,7 @@
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="32dp"
android:focusable="false"
style="?android:attr/progressBarStyleHorizontal"/>
<TextView android:id="@id/exo_duration"
......
......@@ -17,8 +17,8 @@
<style name="ExoMediaButton">
<item name="android:background">@null</item>
<item name="android:layout_width">71dip</item>
<item name="android:layout_height">52dip</item>
<item name="android:layout_width">71dp</item>
<item name="android:layout_height">52dp</item>
</style>
<style name="ExoMediaButton.Previous">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment