Add back the background when we show the action bar
This change fix the following UI issues:
1. We add a black backgorund when ActionBar shows and remove it
when we hide the action bar.
2. Make the postion of video stable when opening
3. Prevent glitching when opening a video
4. Make it really full-screen.
5. Hide ControlOverlay at begining.
bug:6519765
bug:6491674
Change-Id: I3ab033642df2c4a158b99385b02e3e967eebeabd
diff --git a/res/layout/movie_view.xml b/res/layout/movie_view.xml
index 4e645cf..75b8dfd 100644
--- a/res/layout/movie_view.xml
+++ b/res/layout/movie_view.xml
@@ -15,13 +15,13 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/movie_view_root"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
+ android:id="@+id/movie_view_root"
+ android:background="@android:color/black"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<VideoView android:id="@+id/surface_view"
+ android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
-
</RelativeLayout>
diff --git a/src/com/android/gallery3d/app/MovieActivity.java b/src/com/android/gallery3d/app/MovieActivity.java
index b0e53c4..78fe1ee 100644
--- a/src/com/android/gallery3d/app/MovieActivity.java
+++ b/src/com/android/gallery3d/app/MovieActivity.java
@@ -68,7 +68,9 @@
setContentView(R.layout.movie_view);
View rootView = findViewById(R.id.movie_view_root);
- rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Intent intent = getIntent();
initializeActionBar(intent);
mFinishOnCompletion = intent.getBooleanExtra(
diff --git a/src/com/android/gallery3d/app/MovieControllerOverlay.java b/src/com/android/gallery3d/app/MovieControllerOverlay.java
index ae9f085..f2c9e05 100644
--- a/src/com/android/gallery3d/app/MovieControllerOverlay.java
+++ b/src/com/android/gallery3d/app/MovieControllerOverlay.java
@@ -17,6 +17,7 @@
package com.android.gallery3d.app;
import android.content.Context;
+import android.graphics.Rect;
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
@@ -227,6 +228,7 @@
}
private void startHiding() {
+ startHideAnimation(background);
startHideAnimation(timeBar);
startHideAnimation(playPauseReplayView);
}
@@ -302,36 +304,54 @@
return true;
}
+ // The paddings of 4 sides which covered by system components. E.g.
+ // +-----------------+\
+ // | Action Bar | insets.top
+ // +-----------------+/
+ // | |
+ // | Content Area | insets.right = insets.left = 0
+ // | |
+ // +-----------------+\
+ // | Navigation Bar | insets.bottom
+ // +-----------------+/
+ // Please see View.fitSystemWindows() for more details.
+ private final Rect mWindowInsets = new Rect();
+
@Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int bw;
- int bh;
- int y;
- int h = b - t;
- int w = r - l;
+ protected boolean fitSystemWindows(Rect insets) {
+ // We don't set the paddings of this View, otherwise,
+ // the content will get cropped outside window
+ mWindowInsets.set(insets);
+ return true;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ Rect insets = mWindowInsets;
+ int pl = insets.left; // the left paddings
+ int pr = insets.right;
+ int pt = insets.top;
+ int pb = insets.bottom;
+
+ int h = bottom - top;
+ int w = right - left;
boolean error = errorView.getVisibility() == View.VISIBLE;
- bw = timeBar.getBarHeight();
- bh = bw;
- y = b - bh;
+ int y = h - pb;
+ // Put both TimeBar and Background just above the bottom system component.
+ // But extend the background to the width of the screen, since we don't
+ // care if it will be covered by a system component and it looks better.
+ background.layout(0, y - timeBar.getBarHeight(), w, y);
+ timeBar.layout(pl, y - timeBar.getPreferredHeight(), w - pr, y);
- background.layout(l, y, r, b);
-
- timeBar.layout(l, b - timeBar.getPreferredHeight(), r, b);
// Needed, otherwise the framework will not re-layout in case only the padding is changed
timeBar.requestLayout();
- // play pause / next / previous buttons
- int cx = l + w / 2; // center x
- int playbackButtonsCenterline = t + h / 2;
- bw = playPauseReplayView.getMeasuredWidth();
- bh = playPauseReplayView.getMeasuredHeight();
- playPauseReplayView.layout(
- cx - bw / 2, playbackButtonsCenterline - bh / 2, cx + bw / 2,
- playbackButtonsCenterline + bh / 2);
+ // Put the play/pause/next/ previous button in the center of the screen
+ layoutCenteredView(playPauseReplayView, 0, 0, w, h);
if (mainView != null) {
- layoutCenteredView(mainView, l, t, r, b);
+ layoutCenteredView(mainView, 0, 0, w, h);
}
}
diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java
index 565d2b2..13a77f4 100644
--- a/src/com/android/gallery3d/app/MoviePlayer.java
+++ b/src/com/android/gallery3d/app/MoviePlayer.java
@@ -16,7 +16,6 @@
package com.android.gallery3d.app;
-import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -25,6 +24,7 @@
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
+import android.graphics.Color;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
@@ -60,18 +60,20 @@
private static final String CMDNAME = "command";
private static final String CMDPAUSE = "pause";
+ private static final long BLACK_TIMEOUT = 500;
+
// If we resume the acitivty with in RESUMEABLE_TIMEOUT, we will keep playing.
// Otherwise, we pause the player.
private static final long RESUMEABLE_TIMEOUT = 3 * 60 * 1000; // 3 mins
private Context mContext;
private final VideoView mVideoView;
+ private final View mRootView;
private final Bookmarker mBookmarker;
private final Uri mUri;
private final Handler mHandler = new Handler();
private final AudioBecomingNoisyReceiver mAudioBecomingNoisyReceiver;
- private final ActionBar mActionBar;
- private final ControllerOverlay mController;
+ private final MovieControllerOverlay mController;
private long mResumeableTime = Long.MAX_VALUE;
private int mVideoPosition = 0;
@@ -98,6 +100,13 @@
}
};
+ private final Runnable mRemoveBackground = new Runnable() {
+ @Override
+ public void run() {
+ mRootView.setBackground(null);
+ }
+ };
+
private final Runnable mProgressChecker = new Runnable() {
@Override
public void run() {
@@ -106,12 +115,12 @@
}
};
- public MoviePlayer(View rootView, final MovieActivity movieActivity, Uri videoUri,
- Bundle savedInstance, boolean canReplay) {
+ public MoviePlayer(View rootView, final MovieActivity movieActivity,
+ Uri videoUri, Bundle savedInstance, boolean canReplay) {
mContext = movieActivity.getApplicationContext();
+ mRootView = rootView;
mVideoView = (VideoView) rootView.findViewById(R.id.surface_view);
mBookmarker = new Bookmarker(movieActivity);
- mActionBar = movieActivity.getActionBar();
mUri = videoUri;
mController = new MovieControllerOverlay(mContext);
@@ -123,17 +132,31 @@
mVideoView.setOnCompletionListener(this);
mVideoView.setVideoURI(mUri);
mVideoView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
public boolean onTouch(View v, MotionEvent event) {
mController.show();
return true;
}
});
+ // The SurfaceView is transparent before drawing the first frame.
+ // This makes the UI flashing when open a video. (black -> old screen
+ // -> video) However, we have no way to know the timing of the first
+ // frame. So, we hide the VideoView for a while to make sure the
+ // video has been drawn on it.
+ mVideoView.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mVideoView.setVisibility(View.VISIBLE);
+ }
+ }, BLACK_TIMEOUT);
+
// When the user touches the screen or uses some hard key, the framework
// will change system ui visibility from invisible to visible. We show
// the media control and enable system UI (e.g. ActionBar) to be visible at this point
mVideoView.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener() {
+ @Override
public void onSystemUiVisibilityChange(int visibility) {
int diff = mLastSystemUiVis ^ visibility;
mLastSystemUiVis = visibility;
@@ -141,6 +164,19 @@
&& (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
mAllowShowingSystemUI = true;
mController.show();
+
+ // We need to set the background to clear ghosting images
+ // when ActionBar slides in. However, if we keep the background,
+ // there will be one additional layer in HW composer, which is bad
+ // to battery. As a solution, we remove the background when we
+ // hide the action bar
+ mHandler.removeCallbacks(mRemoveBackground);
+ mRootView.setBackgroundColor(Color.BLACK);
+ } else {
+ mHandler.removeCallbacks(mRemoveBackground);
+
+ // Wait for the slide out animation, one second should be enough
+ mHandler.postDelayed(mRemoveBackground, 1000);
}
}
});
@@ -267,6 +303,7 @@
mHandler.postDelayed(mPlayingChecker, 250);
} else {
mController.showPlaying();
+ mController.hide();
}
mVideoView.start();