CommonControllerOverlay.java revision 634248d313c88f14ff851e7b6769b432ce45e15e
13f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu/* 23f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * Copyright (C) 2012 The Android Open Source Project 33f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * 43f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 53f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * you may not use this file except in compliance with the License. 63f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * You may obtain a copy of the License at 73f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * 83f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * http://www.apache.org/licenses/LICENSE-2.0 93f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * 103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * Unless required by applicable law or agreed to in writing, software 113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * distributed under the License is distributed on an "AS IS" BASIS, 123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * See the License for the specific language governing permissions and 143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * limitations under the License. 153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu */ 163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhupackage com.android.gallery3d.app; 183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.content.Context; 20634248d313c88f14ff851e7b6769b432ce45e15eztenghuiimport android.content.res.Resources; 213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.graphics.Rect; 223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.Gravity; 233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.KeyEvent; 243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.MotionEvent; 253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.View; 263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.View.OnClickListener; 273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.FrameLayout; 283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.ImageView; 293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.ImageView.ScaleType; 303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.LinearLayout; 313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.ProgressBar; 323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.RelativeLayout; 333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.TextView; 343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport com.android.gallery3d.R; 363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu/** 383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * The common playback controller for the Movie Player or Video Trimming. 393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu */ 403f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhupublic abstract class CommonControllerOverlay extends FrameLayout implements 413f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ControllerOverlay, 423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu OnClickListener, 433f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu TimeBar.Listener { 443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected enum State { 463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu PLAYING, 473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu PAUSED, 483f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ENDED, 493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ERROR, 503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu LOADING 513f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private static final float ERROR_MESSAGE_RELATIVE_PADDING = 1.0f / 6; 543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected Listener mListener; 563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final View mBackground; 583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected TimeBar mTimeBar; 593f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 603f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected View mMainView; 613f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final LinearLayout mLoadingView; 623f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final TextView mErrorView; 633f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final ImageView mPlayPauseReplayView; 643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected State mState; 663f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 673f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected boolean mCanReplay = true; 683f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 693f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public CommonControllerOverlay(Context context) { 703f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super(context); 713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mState = State.LOADING; 733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // TODO: Move the following layout code into xml file. 743f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu LayoutParams wrapContent = 753f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 763f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu LayoutParams matchParent = 773f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 783f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 793f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mBackground = new View(context); 803f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mBackground.setBackgroundColor(context.getResources().getColor(R.color.darker_transparent)); 813f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu addView(mBackground, matchParent); 823f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 833f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // Depending on the usage, the timeBar can show a single scrubber, or 843f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // multiple ones for trimming. 853f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu createTimeBar(context); 863f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu addView(mTimeBar, wrapContent); 87634248d313c88f14ff851e7b6769b432ce45e15eztenghui mTimeBar.setContentDescription( 88634248d313c88f14ff851e7b6769b432ce45e15eztenghui context.getResources().getString(R.string.accessibility_time_bar)); 893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView = new LinearLayout(context); 903f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView.setOrientation(LinearLayout.VERTICAL); 913f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView.setGravity(Gravity.CENTER_HORIZONTAL); 923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ProgressBar spinner = new ProgressBar(context); 933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu spinner.setIndeterminate(true); 943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView.addView(spinner, wrapContent); 953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu TextView loadingText = createOverlayTextView(context); 963f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu loadingText.setText(R.string.loading_video); 973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView.addView(loadingText, wrapContent); 983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu addView(mLoadingView, wrapContent); 993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView = new ImageView(context); 1013f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setImageResource(R.drawable.ic_vidcontrol_play); 102634248d313c88f14ff851e7b6769b432ce45e15eztenghui mPlayPauseReplayView.setContentDescription( 103634248d313c88f14ff851e7b6769b432ce45e15eztenghui context.getResources().getString(R.string.accessibility_play_video)); 1043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setBackgroundResource(R.drawable.bg_vidcontrol); 1053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setScaleType(ScaleType.CENTER); 1063f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setFocusable(true); 1073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setClickable(true); 1083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setOnClickListener(this); 1093f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu addView(mPlayPauseReplayView, wrapContent); 1103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mErrorView = createOverlayTextView(context); 1123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu addView(mErrorView, matchParent); 1133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu RelativeLayout.LayoutParams params = 1153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu new RelativeLayout.LayoutParams( 1163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 1173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setLayoutParams(params); 1183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu hide(); 1193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu abstract protected void createTimeBar(Context context); 1223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private TextView createOverlayTextView(Context context) { 1243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu TextView view = new TextView(context); 1253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu view.setGravity(Gravity.CENTER); 1263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu view.setTextColor(0xFFFFFFFF); 1273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu view.setPadding(0, 15, 0, 15); 1283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return view; 1293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void setListener(Listener listener) { 1333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu this.mListener = listener; 1343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void setCanReplay(boolean canReplay) { 1383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu this.mCanReplay = canReplay; 1393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1403f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1413f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public View getView() { 1433f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return this; 1443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void showPlaying() { 1483f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mState = State.PLAYING; 1493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu showMainView(mPlayPauseReplayView); 1503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1513f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void showPaused() { 1543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mState = State.PAUSED; 1553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu showMainView(mPlayPauseReplayView); 1563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1593f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void showEnded() { 1603f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mState = State.ENDED; 16162e98689761a7900dd7e556d04bde8955b94ebdbBobby Georgescu if (mCanReplay) showMainView(mPlayPauseReplayView); 1623f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1633f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void showLoading() { 1663f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mState = State.LOADING; 1673f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu showMainView(mLoadingView); 1683f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1693f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1703f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void showErrorMessage(String message) { 1723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mState = State.ERROR; 1733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int padding = (int) (getMeasuredWidth() * ERROR_MESSAGE_RELATIVE_PADDING); 1743f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mErrorView.setPadding( 1753f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu padding, mErrorView.getPaddingTop(), padding, mErrorView.getPaddingBottom()); 1763f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mErrorView.setText(message); 1773f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu showMainView(mErrorView); 1783f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1793f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1803f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1813f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void setTimes(int currentTime, int totalTime, 1823f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int trimStartTime, int trimEndTime) { 1833f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBar.setTime(currentTime, totalTime, trimStartTime, trimEndTime); 1843f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1853f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1863f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void hide() { 1873f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setVisibility(View.INVISIBLE); 1883f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView.setVisibility(View.INVISIBLE); 1893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mBackground.setVisibility(View.INVISIBLE); 1903f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBar.setVisibility(View.INVISIBLE); 1913f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setVisibility(View.INVISIBLE); 1923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setFocusable(true); 1933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu requestFocus(); 1943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1963f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private void showMainView(View view) { 1973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mMainView = view; 1983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mErrorView.setVisibility(mMainView == mErrorView ? View.VISIBLE : View.INVISIBLE); 1993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mLoadingView.setVisibility(mMainView == mLoadingView ? View.VISIBLE : View.INVISIBLE); 2003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setVisibility( 2013f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mMainView == mPlayPauseReplayView ? View.VISIBLE : View.INVISIBLE); 2023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu show(); 2033f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2063f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void show() { 2073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu updateViews(); 2083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setVisibility(View.VISIBLE); 2093f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setFocusable(false); 2103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onClick(View view) { 2143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mListener != null) { 2153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (view == mPlayPauseReplayView) { 2163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mState == State.ENDED) { 2173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mCanReplay) { 2183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onReplay(); 2193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } else if (mState == State.PAUSED || mState == State.PLAYING) { 2213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onPlayPause(); 2223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public boolean onKeyDown(int keyCode, KeyEvent event) { 2293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return super.onKeyDown(keyCode, event); 2303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public boolean onTouchEvent(MotionEvent event) { 2343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (super.onTouchEvent(event)) { 2353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return true; 2363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return false; 2383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2403f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // The paddings of 4 sides which covered by system components. E.g. 2413f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // +-----------------+\ 2423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // | Action Bar | insets.top 2433f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // +-----------------+/ 2443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // | | 2453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // | Content Area | insets.right = insets.left = 0 2463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // | | 2473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // +-----------------+\ 2483f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // | Navigation Bar | insets.bottom 2493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // +-----------------+/ 2503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // Please see View.fitSystemWindows() for more details. 2513f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private final Rect mWindowInsets = new Rect(); 2523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected boolean fitSystemWindows(Rect insets) { 2553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // We don't set the paddings of this View, otherwise, 2563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // the content will get cropped outside window 2573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mWindowInsets.set(insets); 2583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return true; 2593f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2603f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2613f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2623f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 2633f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu Rect insets = mWindowInsets; 2643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int pl = insets.left; // the left paddings 2653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int pr = insets.right; 2663f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int pt = insets.top; 2673f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int pb = insets.bottom; 2683f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2693f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int h = bottom - top; 2703f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int w = right - left; 2713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu boolean error = mErrorView.getVisibility() == View.VISIBLE; 2723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int y = h - pb; 2743f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // Put both TimeBar and Background just above the bottom system 2753f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // component. 2763f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // But extend the background to the width of the screen, since we don't 2773f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // care if it will be covered by a system component and it looks better. 2783f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mBackground.layout(0, y - mTimeBar.getBarHeight(), w, y); 2793f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBar.layout(pl, y - mTimeBar.getPreferredHeight(), w - pr, y); 2803f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2813f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // Put the play/pause/next/ previous button in the center of the screen 2823f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu layoutCenteredView(mPlayPauseReplayView, 0, 0, w, h); 2833f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2843f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mMainView != null) { 2853f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu layoutCenteredView(mMainView, 0, 0, w, h); 2863f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2873f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2883f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private void layoutCenteredView(View view, int l, int t, int r, int b) { 2903f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int cw = view.getMeasuredWidth(); 2913f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int ch = view.getMeasuredHeight(); 2923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int cl = (r - l - cw) / 2; 2933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int ct = (b - t - ch) / 2; 2943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu view.layout(cl, ct, cl + cw, ct + ch); 2953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2963f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 2993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onMeasure(widthMeasureSpec, heightMeasureSpec); 3003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu measureChildren(widthMeasureSpec, heightMeasureSpec); 3013f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3033f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected void updateViews() { 3043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mBackground.setVisibility(View.VISIBLE); 3053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBar.setVisibility(View.VISIBLE); 306634248d313c88f14ff851e7b6769b432ce45e15eztenghui Resources resources = getContext().getResources(); 307634248d313c88f14ff851e7b6769b432ce45e15eztenghui int imageResource = R.drawable.ic_vidcontrol_reload; 308634248d313c88f14ff851e7b6769b432ce45e15eztenghui String contentDescription = resources.getString(R.string.accessibility_reload_video); 309634248d313c88f14ff851e7b6769b432ce45e15eztenghui if (mState == State.PAUSED) { 310634248d313c88f14ff851e7b6769b432ce45e15eztenghui imageResource = R.drawable.ic_vidcontrol_play; 311634248d313c88f14ff851e7b6769b432ce45e15eztenghui contentDescription = resources.getString(R.string.accessibility_play_video); 312634248d313c88f14ff851e7b6769b432ce45e15eztenghui } else if (mState == State.PLAYING) { 313634248d313c88f14ff851e7b6769b432ce45e15eztenghui imageResource = R.drawable.ic_vidcontrol_pause; 314634248d313c88f14ff851e7b6769b432ce45e15eztenghui contentDescription = resources.getString(R.string.accessibility_pause_video); 315634248d313c88f14ff851e7b6769b432ce45e15eztenghui } 316634248d313c88f14ff851e7b6769b432ce45e15eztenghui 317634248d313c88f14ff851e7b6769b432ce45e15eztenghui mPlayPauseReplayView.setImageResource(imageResource); 318634248d313c88f14ff851e7b6769b432ce45e15eztenghui mPlayPauseReplayView.setContentDescription(contentDescription); 3193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayPauseReplayView.setVisibility( 3203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu (mState != State.LOADING && mState != State.ERROR && 3213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu !(mState == State.ENDED && !mCanReplay)) 3223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ? View.VISIBLE : View.GONE); 3233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu requestLayout(); 3243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // TimeBar listener 3273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onScrubbingStart() { 3303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onSeekStart(); 3313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onScrubbingMove(int time) { 3353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onSeekMove(time); 3363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onScrubbingEnd(int time, int trimStartTime, int trimEndTime) { 3403f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onSeekEnd(time, trimStartTime, trimEndTime); 3413f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu} 343