videoview 横竖屏切换
2016-01-22 18:14
309 查看
Android videoview 横竖屏切换,主要是对各种状态封装了一下,以后移植不需要考虑这些状态。然后横竖屏,对布局结构有点限制,要处于上层才能全屏
public class MainActivity extends Activity { public static final String URL_VIDEO = "http://static.wezeit.com/o_1a9jjk9021fkt7vs1mlo16i91gvn9.mp4"; @Bind(R.id.webview) public WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initWidget(); setupListener(); loadData(); } private void initView(){ ButterKnife.bind(this); initFakeStatusBarHeight(true); } private void initWidget(){ initWebViewSetting(mWebView); } private void setupListener(){ setupWebViewListener(); } private void loadData(){ View view = findViewById(R.id.activity_video_rl); initVideoMode(view); String url = "http://www.wezeit.com/wap/297121.html"; loadWebviewUrl(url); } protected void loadWebviewUrl(String url){ DebugTools.d("js2 discovery2 jump3 vote2 news2 current url: " + url); if(!TextUtils.isEmpty(url)){ mWebView.loadUrl(url); } } protected int mPixelInsetTop; protected void initFakeStatusBarHeight(boolean isNewsPage){ View statusbarBgLayout = (View)findViewById(R.id.statusbar_bg_layout); if(statusbarBgLayout == null){ return; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { mPixelInsetTop = CommonTools.getStatusbarHeight(this); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)statusbarBgLayout.getLayoutParams(); params.height = mPixelInsetTop; statusbarBgLayout.setLayoutParams(params); statusbarBgLayout.setBackgroundResource(R.color.black); }else{ mPixelInsetTop = 0; statusbarBgLayout.setVisibility(View.GONE); } } //----------videoview---------------- private VideoViewHolder mVideoHolder; private VideoView mVideoView; private VideoViewHolderControl mVideoControl; private void initVideoMode(View view){ showFullScreen(false); mVideoView = (VideoView) view.findViewById(R.id.videoview); mVideoHolder = new VideoViewHolder(view); mVideoHolder.imgIv.setImageResource(R.mipmap.index); mVideoControl = new VideoViewHolderControl(mVideoHolder, mVideoView, URL_VIDEO); setupVideoControlListener(mVideoControl); mVideoControl.setup(); setVideoViewLayout(false); } private void setupVideoControlListener(VideoViewHolderControl control){ control.setOnVideoControlListener(new VideoViewHolderControl.OnVideoControlProxy() { @Override public void onCompletion() { DebugTools.d("video2 onCompletion"); setFullScreen(false); } @Override public void onClickHalfFullScreen() { boolean isFull = isFullScreen(); setFullScreen(!isFull); } @Override public void onError(int code, String msg) { } }); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { initHalfFullState(true); } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { initHalfFullState(false); } } private void initHalfFullState(boolean isFull){ DebugTools.d("video2 initHalfFullState isFull: " + isFull); setVideoViewLayout(isFull); showFullScreen(isFull); } //---------videoview fullscreen--------- private void showFullScreen(boolean isFullScreen){ if(isFullScreen){ // //不显示程序的标题栏 hideNavigationBar(); }else{ showNavigationBar(); } } protected void setFullScreen(boolean isFull){ if(isFull){ if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } }else{ if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } } protected boolean isFullScreen(){ return getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; } private void showNavigationBar(){ View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } public void hideNavigationBar() { int uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN; // hide status bar getWindow().getDecorView().setSystemUiVisibility(uiFlags); } private void setVideoViewLayout(boolean isFull){ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mVideoHolder.videoRl.getLayoutParams(); RelativeLayout.LayoutParams controlParams = (RelativeLayout.LayoutParams)mVideoHolder.mediaControl.getLayoutParams(); RelativeLayout.LayoutParams indexImageParams = (RelativeLayout.LayoutParams)mVideoHolder.imgIv.getLayoutParams(); int videoMarginTop = (int)getResources().getDimension(R.dimen.library_video_video_margin_top) + mPixelInsetTop; if(isFull){ params.height = LayoutParams.MATCH_PARENT; params.addRule(RelativeLayout.CENTER_IN_PARENT); params.setMargins(0, 0, 0, 0); controlParams.setMargins(0, 0, 0, 0); indexImageParams.height = LayoutParams.MATCH_PARENT; indexImageParams.setMargins(0, 0, 0, 0); }else{ params.height = DisplayUtil.dip2px(this, 202); params.addRule(RelativeLayout.ALIGN_PARENT_TOP); params.setMargins(0, videoMarginTop, 0, 0); controlParams.setMargins(0, 0, 0, 0); indexImageParams.height = DisplayUtil.dip2px(this, 202); indexImageParams.setMargins(0, 0, 0, 0); } mVideoHolder.videoRl.setLayoutParams(params); mVideoHolder.mediaControl.setLayoutParams(controlParams); mVideoHolder.imgIv.setLayoutParams(indexImageParams); } //--------------webview-------------- protected void initWebViewStorage(WebView webview){ webview.getSettings().setDomStorageEnabled(true); webview.getSettings().setAppCacheMaxSize(1024*1024*8); String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath(); webview.getSettings().setAllowFileAccess(true); webview.getSettings().setAppCacheEnabled(true); webview.getSettings().setDatabaseEnabled(true); webview.getSettings().setDatabasePath(appCachePath); } protected void initWebViewSetting(WebView webview){ WebSettings webseting = webview.getSettings(); // webseting.setRenderPriority(RenderPriority.HIGH); webseting.setJavaScriptEnabled(true); // webseting.setPluginsEnabled(true); webseting.setSupportZoom(true); webview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); webseting.setUseWideViewPort(true); webseting.setLoadWithOverviewMode(true); initWebViewStorage(webview); } protected void setupWebViewListener(){ mWebView.setWebViewClient(new WebViewClient() { }); mWebView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); } }); } @Override public boolean onKeyDown(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ handleClickBack(); return true; } return super.onKeyDown(keyCode, event); } protected void handleClickBack(){ if(isFullScreen()){ setFullScreen(false); return; } if (mWebView != null){ mWebView.onPause(); } finish(); } @Override protected void onDestroy() { ButterKnife.unbind(this); super.onDestroy(); } }
VideoViewHolderControl,状态控制器,里面集成了视频的基本操作
public class VideoViewHolderControl { private VideoViewHolder mHolder; private VideoView mVideoView; private String mUrl; private boolean mIsFullScreen = false; private boolean mIsFullScreenMode = false; public VideoViewHolderControl(VideoViewHolder holder, VideoView videoView, String url){ mHolder = holder; mVideoView = videoView; mUrl = url; // mUrl = "http://img.owspace.com/V_tnh2100_1453346133.2098116.m3u8"; } public void setup(){ setupPlayListener(mHolder); showInitStateState(mHolder); } public void play(){ if(mHolder != null){ handleStartPlayVideo(mHolder); } } public void setIsFullScreenMode(boolean isFullMode){ mIsFullScreenMode = isFullMode; if(mIsFullScreenMode){ if(mHolder != null){ mHolder.halfFullIb.setImageResource(R.mipmap.library_video_mediacontroller_to_half); hideFullHalIb(mHolder); } } } private void hideFullHalIb(VideoViewHolder holder){ if(holder == null){ return; } holder.halfFullIb.setVisibility(View.GONE); RelativeLayout.LayoutParams totalTimeParams = (RelativeLayout.LayoutParams)holder.totalTimeTv.getLayoutParams(); totalTimeParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); totalTimeParams.setMargins(0, 0, (int)DisplayUtil.dpToPx(10), 0); holder.totalTimeTv.setLayoutParams(totalTimeParams); } private void setupPlayListener(final VideoViewHolder holder){ holder.playPauseIb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { handleStartPlayVideo(holder); } }); holder.imgIv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { handleStartPlayVideo(holder); } }); holder.playSymbolIv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { handleStartPlayVideo(holder); } }); if(holder.halfFullIb != null){ holder.halfFullIb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(mIsFullScreenMode){ if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickHalfFullScreen(); } }else{ if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickHalfFullScreen(); mIsFullScreen = !mIsFullScreen; setHalfFullScreenState(holder, mIsFullScreen); } } } }); } if(holder.backIb != null){ holder.backIb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(mIsFullScreenMode){ if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickHalfFullScreen(); } } } }); } } private void setHalfFullScreenState(VideoViewHolder holder, boolean isFull){ if(isFull){ holder.halfFullIb.setImageResource(R.mipmap.library_video_mediacontroller_to_half); }else{ holder.halfFullIb.setImageResource(R.mipmap.library_video_mediacontroller_to_full); } } private void handleStartPlayVideo(VideoViewHolder holder){ DebugTools.d("video2 handleStartPlayVideo mPlayState: " + mPlayState); if(mPlayState == PlayState.INIT){ if(mVideoView == null){ return; } if(TextUtils.isEmpty(mUrl)){ if(mOnVideoControlListener != null){ mOnVideoControlListener.onError(0, "视频地址为空"); } return; } if(mVideoView.getVisibility() != View.VISIBLE){ mVideoView.setVisibility(View.VISIBLE); } initVideoView(holder, mVideoView); handlePrepareVideo(holder); setupVideoViewListener(mVideoView, holder); DebugTools.d("video2 handleStartPlayVideo setVideoPath-------------"); mVideoView.setVideoPath(mUrl); if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickPlay(); } }else if(mPlayState == PlayState.PAUSE){ handlePlayVideo(holder); if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickResume(); } }else if(mPlayState == PlayState.PLAYING){ handlePauseVideo(holder); if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickPause(); } } } private void handlePrepareVideo(final VideoViewHolder holder){ showPreparePlayState(holder); } private void handlePlayVideo(final VideoViewHolder holder){ showPlayingState(holder);; mVideoView.start(); } private void handlePauseVideo(final VideoViewHolder holder){ showPauseState(holder); mVideoView.pause(); } public void pause(){ if(mPlayState == PlayState.PLAYING){ handlePauseVideo(mHolder); if(mOnVideoControlListener != null){ mOnVideoControlListener.onClickPause(); } }else if(mPlayState == PlayState.PREPARE){ stop(); } } public void stop(){ if(!isInIdleState()){ stopVideo(mHolder, mVideoView); } } private void stopVideo(VideoViewHolder holder, VideoView videoView){ DebugTools.d("video2 stopVideo videoView null: " + (videoView == null)); if(videoView != null){ videoView.setVisibility(View.GONE); videoView.stopPlayback(); holder.pb.setVisibility(View.GONE); showInitStateState(holder); } } private boolean isInIdleState(){ return mPlayState == PlayState.INIT; } private PlayState mPlayState = PlayState.INIT; private enum PlayState{ INIT, PREPARE, PLAYING, PAUSE } private void showPlayingState(VideoViewHolder holder){ mPlayState = PlayState.PLAYING; updateViewVisibleState(holder.pb, View.GONE); updateViewVisibleState(holder.imgIv, View.INVISIBLE); updateViewVisibleState(holder.seekBar, View.VISIBLE); updateViewVisibleState(holder.playSymbolIv, View.INVISIBLE); holder.playPauseIb.setImageResource(R.mipmap.library_video_mediacontroller_pause); sendDismissVideoControlBarDelay(holder); } private void showPauseState(VideoViewHolder holder){ mPlayState = PlayState.PAUSE; updateViewVisibleState(holder.pb, View.GONE); updateViewVisibleState(holder.imgIv, View.INVISIBLE); updateViewVisibleState(holder.seekBar, View.VISIBLE); updateViewVisibleState(holder.mediaControl, View.VISIBLE); updateViewVisibleState(holder.backIb, View.VISIBLE); updateViewVisibleState(holder.playSymbolIv, View.VISIBLE); holder.playPauseIb.setImageResource(R.mipmap.library_video_mediacontroller_play); mHandler.removeMessages(Constants.MSG_DISMISS_VIDEO_CONTROL_BAR); } private void showPreparePlayState(VideoViewHolder holder){ mPlayState = PlayState.PREPARE; if(!mIsFullScreenMode){ updateViewVisibleState(holder.imgIv, View.INVISIBLE); } holder.playPauseIb.setImageResource(R.mipmap.library_video_mediacontroller_pause); updateViewVisibleState(holder.pb, View.VISIBLE); updateViewVisibleState(holder.seekBar, View.VISIBLE); updateViewVisibleState(holder.mediaControl, View.INVISIBLE); updateViewVisibleState(holder.backIb, View.INVISIBLE); updateViewVisibleState(holder.playSymbolIv, View.INVISIBLE); } private void showInitStateState(VideoViewHolder holder){ mPlayState = PlayState.INIT; holder.seekBar.setProgress(0); holder.playPauseIb.setImageResource(R.mipmap.library_video_mediacontroller_play); updateViewVisibleState(holder.pb, View.GONE); updateViewVisibleState(holder.imgIv, View.VISIBLE); updateViewVisibleState(holder.seekBar, View.INVISIBLE); updateViewVisibleState(holder.mediaControl, View.INVISIBLE); updateViewVisibleState(holder.backIb, View.INVISIBLE); updateViewVisibleState(holder.playSymbolIv, View.VISIBLE); mHandler.removeMessages(Constants.MSG_DISMISS_VIDEO_CONTROL_BAR); } private void updateViewVisibleState(View view, int visibleState){ if(!mIsFullScreenMode && view == mHolder.backIb){ return; } if(view == null){ return; } if(view.getVisibility() != visibleState){ view.setVisibility(visibleState); } } private void initVideoView(VideoViewHolder holder, VideoView videoView){ videoView.setMediaController(holder.mediaControl); holder.mediaControl.setMediaPlayer(videoView); //让VideiView获取焦点 videoView.requestFocus(); } private void setupVideoViewListener(final VideoView videoView, final VideoViewHolder holder){ videoView.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { DebugTools.d("video2 setOnPreparedListener onCompletion---, mPlayState: " + mPlayState); if(videoView != null){ if(mp != null){ mp.reset(); } videoView.seekTo(0); videoView.stopPlayback(); showInitStateState(holder); } if(mOnVideoControlListener != null){ mOnVideoControlListener.onCompletion(); } } }); videoView.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { // mVideoView.setBackgroundColor(Color.TRANSPARENT); DebugTools.d("video2 setOnPreparedListener onPrepared, mPlayState: " + mPlayState); // if(!(mPlayState == PlayState.PREPARE || mPlayState == PlayState.INIT)){ // return; // } mVideoView.start(); showPlayingState(holder); holder.mediaControl.show(); updateViewVisibleState(holder.backIb, View.VISIBLE); mHandler.sendEmptyMessageDelayed(Constants.MSG_SET_VIDEO_VIEW_TRANSPARENT, Constants.DELAY_MSG_SET_VIDEO_VIEW_TRANSPARENT); sendDismissVideoControlBarDelay(holder); DebugTools.d("video2 onPrepared mProgress: " + mProgress); if(mIsFullScreenMode && mProgress > 1000){ seekTo(mProgress); } if(mOnVideoControlListener != null){ mOnVideoControlListener.onPrepared(); } } }); ((WylVideoView)videoView).setOnGestureListener(new OnGestureListener() { @Override public void onSingleTapConfirmed() { boolean isShow = (holder.mediaControl.getVisibility() == View.VISIBLE); showVideoControlBar(holder, !isShow); } @Override public void onDoubleTap() { handleStartPlayVideo(holder); } }); if(holder.videoRl != null){ holder.videoRl.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean isShow = (holder.mediaControl.getVisibility() == View.VISIBLE); showVideoControlBar(holder, !isShow); } }); } holder.mediaControl.setAdditionalSeekBarListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { DebugTools.d("video2 sbar2 onStopTrackingTouch"); sendDismissVideoControlBarDelay(holder); } @Override public void onStartTrackingTouch(SeekBar seekBar) { DebugTools.d("video2 sbar2 onStartTrackingTouch"); mHandler.removeMessages(Constants.MSG_DISMISS_VIDEO_CONTROL_BAR); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { DebugTools.d("video2 sbar2 onProgressChanged"); } }); DebugTools.d("video2 setupVideoViewListener when click play video"); } private void showVideoControlBar(final VideoViewHolder holder, final boolean isShow){ mHandler.removeMessages(Constants.MSG_DISMISS_VIDEO_CONTROL_BAR); updateViewVisibleState(holder.mediaControl, View.VISIBLE); updateViewVisibleState(holder.backIb, View.VISIBLE); Animation anim = null; if(isShow){ anim = new TranslateAnimation(0, 0, 100, 0); }else{ anim = new TranslateAnimation(0, 0, 0, 100); } anim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if(isShow){ updateViewVisibleState(holder.mediaControl, View.VISIBLE); updateViewVisibleState(holder.backIb, View.VISIBLE); sendDismissVideoControlBarDelay(holder); }else{ updateViewVisibleState(holder.mediaControl, View.INVISIBLE); updateViewVisibleState(holder.backIb, View.INVISIBLE); } } }); anim.setDuration(300); holder.mediaControl.startAnimation(anim); if(holder.backIb != null){ Animation backAnim = null; if(isShow){ backAnim = new AlphaAnimation(0, 1); }else{ backAnim = new AlphaAnimation(1, 0); } backAnim.setDuration(300); holder.backIb.startAnimation(backAnim); } } private void sendDismissVideoControlBarDelay(VideoViewHolder holder){ Message msg = mHandler.obtainMessage(Constants.MSG_DISMISS_VIDEO_CONTROL_BAR, holder); mHandler.sendMessageDelayed(msg, Constants.DELAY_MSG_DISMISS_VIDEO_CONTROL_BAR); } private Handler mHandler = new Handler(){ public void handleMessage(Message msg) { switch(msg.what){ case Constants.MSG_SET_VIDEO_VIEW_TRANSPARENT: setVideoViewTranslate(); break; case Constants.MSG_DISMISS_VIDEO_CONTROL_BAR: VideoViewHolder holder = (VideoViewHolder)msg.obj; showVideoControlBar(holder, false); break; } }; }; private void setVideoViewTranslate(){ if(mVideoView != null){ mVideoView.setBackgroundColor(Color.TRANSPARENT); } } private int mProgress; public void setProgress(int pos){ mProgress = pos; } private void seekTo(int pos){ if(mHolder != null && mHolder.mediaControl != null){ mHolder.mediaControl.seekTo(pos); } } public static class VideoViewHolder{ public WylMediaControl mediaControl; // public ImageView shareIv; public ImageView playPauseIb; public SeekBar seekBar; public ProgressBar pb; public ImageView imgIv; public ImageView playSymbolIv; public RelativeLayout videoRl; public ImageButton halfFullIb; public ImageButton backIb; public TextView totalTimeTv; public VideoViewHolder(View convertView){ mediaControl = (WylMediaControl) convertView.findViewById(R.id.media_control); // shareIv = (ImageView) convertView.findViewById(R.id.mediacontroller_share_iv); playPauseIb = (ImageView) convertView.findViewById(R.id.mediacontroller_play_pause); seekBar = (SeekBar) convertView.findViewById(R.id.mediacontroller_seekbar); pb = (ProgressBar) convertView.findViewById(R.id.loading_pb); imgIv = (ImageView) convertView.findViewById(R.id.video_image_iv); playSymbolIv = (ImageView) convertView.findViewById(R.id.play_symbol_iv); videoRl = (RelativeLayout) convertView.findViewById(R.id.video_rl); halfFullIb = (ImageButton) convertView.findViewById(R.id.mediacontroller_half_full_ib); // backIb = (ImageButton) convertView.findViewById(R.id.video_back_iv); totalTimeTv = (TextView) convertView.findViewById(R.id.mediacontroller_time_total); } } private OnVideoControlListener mOnVideoControlListener; public void setOnVideoControlListener(OnVideoControlListener listener){ mOnVideoControlListener = listener; } public interface OnVideoControlListener{ public void onClickPlay(); public void onPrepared(); public void onClickResume(); public void onClickPause(); public void onCompletion(); public void onClickHalfFullScreen(); public void onError(int code, String msg); } public static class OnVideoControlProxy implements OnVideoControlListener{ @Override public void onClickPlay() { } @Override public void onPrepared() { } @Override public void onClickResume() { } @Override public void onClickPause() { } @Override public void onCompletion() { } @Override public void onClickHalfFullScreen() { } @Override public void onError(int code, String msg) { } } }
WylMediaControl,重写了下系统的MediaController,方便自定义
public class WylMediaControl extends MediaController { private MediaPlayerControl mPlayer; private Context mContext; private View mAnchor; private View mRoot; private WindowManager mWindowManager; private Window mWindow; private View mDecor; private WindowManager.LayoutParams mDecorLayoutParams; private ProgressBar mProgress; private TextView mEndTime, mCurrentTime; private boolean mShowing; private boolean mDragging; private static final int sDefaultTimeout = 3000; private static final int FADE_OUT = 1; private static final int SHOW_PROGRESS = 2; private boolean mUseFastForward; private boolean mFromXml; private boolean mListenersSet; private OnClickListener mNextListener, mPrevListener; StringBuilder mFormatBuilder; Formatter mFormatter; private ImageView mPauseButton; // private ImageButton mPauseButton; private ImageButton mFfwdButton; private ImageButton mRewButton; private ImageButton mNextButton; private ImageButton mPrevButton; private ImageView mShareBtn; public WylMediaControl(Context context, AttributeSet attrs) { super(context, attrs); mRoot = this; mContext = context; mUseFastForward = true; mFromXml = true; } @Override public void onFinishInflate() { if (mRoot != null) initControllerView(mRoot); } public WylMediaControl(Context context, boolean useFastForward) { super(context); mContext = context; mUseFastForward = useFastForward; initFloatingWindowLayout(); // initFloatingWindow(); } public WylMediaControl(Context context) { this(context, true); } // private void initFloatingWindow() { // mWindowManager = // (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); // mWindow = PolicyManager.makeNewWindow(mContext); // mWindow.setWindowManager(mWindowManager, null, null); // mWindow.requestFeature(Window.FEATURE_NO_TITLE); // mDecor = mWindow.getDecorView(); // mDecor.setOnTouchListener(mTouchListener); // mWindow.setContentView(this); // mWindow.setBackgroundDrawableResource(android.R.color.transparent); // // // While the media controller is up, the volume control keys should // // affect the media stream type // mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC); // // setFocusable(true); // setFocusableInTouchMode(true); // setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); // requestFocus(); // } // Allocate and initialize the static parts of mDecorLayoutParams. Must // also call updateFloatingWindowLayout() to fill in the dynamic parts // (y and width) before mDecorLayoutParams can be used. private void initFloatingWindowLayout() { mDecorLayoutParams = new WindowManager.LayoutParams(); WindowManager.LayoutParams p = mDecorLayoutParams; p.gravity = Gravity.TOP | Gravity.LEFT; p.height = LayoutParams.WRAP_CONTENT; p.x = 0; p.format = PixelFormat.TRANSLUCENT; p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; p.token = null; p.windowAnimations = 0; // android.R.style.DropDownAnimationDown; } // Update the dynamic parts of mDecorLayoutParams // Must be called with mAnchor != NULL. private void updateFloatingWindowLayout() { int[] anchorPos = new int[2]; mAnchor.getLocationOnScreen(anchorPos); // we need to know the size of the controller so we can properly // position it // within its space mDecor.measure(MeasureSpec.makeMeasureSpec(mAnchor.getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec( mAnchor.getHeight(), MeasureSpec.AT_MOST)); WindowManager.LayoutParams p = mDecorLayoutParams; p.width = mAnchor.getWidth(); p.x = anchorPos[0] + (mAnchor.getWidth() - p.width) / 2; p.y = anchorPos[1] + mAnchor.getHeight() - mDecor.getMeasuredHeight(); } // This is called whenever mAnchor's layout bound changes private OnLayoutChangeListener mLayoutChangeListener = new OnLayoutChangeListener() { public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { updateFloatingWindowLayout(); if (mShowing) { mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams); } } }; private OnTouchListener mTouchListener = new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mShowing) { hide(); } } return false; } }; @Override public void setMediaPlayer(MediaPlayerControl player) { mPlayer = player; updatePausePlay(); } /** * Set the view that acts as the anchor for the control view. This can for * example be a VideoView, or your Activity's main view. When VideoView * calls this method, it will use the VideoView's parent as the anchor. * * @param view * The view to which to anchor the controller when it is visible. */ public void setAnchorView(View view) { // if (mAnchor != null) { // mAnchor.removeOnLayoutChangeListener(mLayoutChangeListener); // } mAnchor = view; // if (mAnchor != null) { // mAnchor.addOnLayoutChangeListener(mLayoutChangeListener); // } if (!mFromXml) { // FrameLayout.LayoutParams frameParams = new // FrameLayout.LayoutParams( // ViewGroup.LayoutParams.MATCH_PARENT, // ViewGroup.LayoutParams.MATCH_PARENT // ); // // removeAllViews(); // View v = makeControllerView(); // addView(v, frameParams); } } private MediaControlListener mMediaControlListener; public interface MediaControlListener{ public void onClickStart(); public void onClickPause(); } /** * Create the view that holds the widgets that control playback. Derived * classes can override this to create their own. * * @return The controller view. * @hide This doesn't work as advertised */ // protected View makeControllerView() { // LayoutInflater inflate = (LayoutInflater) // mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // mRoot = inflate.inflate(com.android.internal.R.layout.media_controller, // null); // // initControllerView(mRoot); // // return mRoot; // } private void initControllerView(View v) { mPauseButton = (ImageView) v.findViewById(R.id.mediacontroller_play_pause); // if (mPauseButton != null) { // mPauseButton.requestFocus(); // mPauseButton.setOnClickListener(mPauseListener); // } if (mShareBtn != null) { // mShareBtn.setOnClickListener(mShareListener); } // mFfwdButton = (ImageButton) v.findViewById(com.android.internal.R.id.ffwd); // if (mFfwdButton != null) { // mFfwdButton.setOnClickListener(mFfwdListener); // if (!mFromXml) { // mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE // : View.GONE); // } // } // // mRewButton = (ImageButton) v.findViewById(com.android.internal.R.id.rew); // if (mRewButton != null) { // mRewButton.setOnClickListener(mRewListener); // if (!mFromXml) { // mRewButton.setVisibility(mUseFastForward ? View.VISIBLE // : View.GONE); // } // } // By default these are hidden. They will be enabled when // setPrevNextListeners() is called // mNextButton = (ImageButton) v.findViewById(com.android.internal.R.id.next); // if (mNextButton != null && !mFromXml && !mListenersSet) { // mNextButton.setVisibility(View.GONE); // } // mPrevButton = (ImageButton) v.findViewById(com.android.internal.R.id.prev); // if (mPrevButton != null && !mFromXml && !mListenersSet) { // mPrevButton.setVisibility(View.GONE); // } mProgress = (ProgressBar) v.findViewById(R.id.mediacontroller_seekbar); if (mProgress != null) { if (mProgress instanceof SeekBar) { SeekBar seeker = (SeekBar) mProgress; seeker.setOnSeekBarChangeListener(mSeekListener); } mProgress.setMax(1000); } mEndTime = (TextView) v.findViewById(R.id.mediacontroller_time_total); mCurrentTime = (TextView) v.findViewById(R.id.mediacontroller_time_current); mFormatBuilder = new StringBuilder(); mFormatter = new Formatter(mFormatBuilder, Locale.getDefault()); installPrevNextListeners(); } /** * Show the controller on screen. It will go away automatically after 3 * seconds of inactivity. */ public void show() { show(sDefaultTimeout); } /** * Disable pause or seek buttons if the stream cannot be paused or seeked. * This requires the control interface to be a MediaPlayerControlExt */ private void disableUnsupportedButtons() { try { if (mPauseButton != null && !mPlayer.canPause()) { mPauseButton.setEnabled(false); } if (mRewButton != null && !mPlayer.canSeekBackward()) { mRewButton.setEnabled(false); } if (mFfwdButton != null && !mPlayer.canSeekForward()) { mFfwdButton.setEnabled(false); } } catch (IncompatibleClassChangeError ex) { // We were given an old version of the interface, that doesn't have // the canPause/canSeekXYZ methods. This is OK, it just means we // assume the media can be paused and seeked, and so we don't // disable // the buttons. } } /** * Show the controller on screen. It will go away automatically after * 'timeout' milliseconds of inactivity. * * @param timeout * The timeout in milliseconds. Use 0 to show the controller * until hide() is called. */ public void show(int timeout) { if (!mShowing && mAnchor != null) { if (mFromXml) { setVisibility(View.VISIBLE); // return; } setProgress(); if (mPauseButton != null) { mPauseButton.requestFocus(); } disableUnsupportedButtons(); // updateFloatingWindowLayout(); // mWindowManager.addView(mDecor, mDecorLayoutParams); mShowing = true; } updatePausePlay(); // cause the progress bar to be updated even if mShowing // was already true. This happens, for example, if we're // paused with the progress bar showing the user hits play. mHandler.sendEmptyMessage(SHOW_PROGRESS); DebugTools.d("control2 show"); Message msg = mHandler.obtainMessage(FADE_OUT); if (timeout != 0) { mHandler.removeMessages(FADE_OUT); mHandler.sendMessageDelayed(msg, timeout); } } public boolean isShowing() { return mShowing; } /** * Remove the controller from the screen. */ public void hide() { // if (mAnchor == null) // return; // // if (mShowing) { // try { // mHandler.removeMessages(SHOW_PROGRESS); // mWindowManager.removeView(mDecor); // } catch (IllegalArgumentException ex) { // Log.w("MediaController", "already removed"); // } // mShowing = false; // } } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { int pos; switch (msg.what) { case FADE_OUT: // hide(); break; case SHOW_PROGRESS: pos = setProgress(); if (!mDragging && mShowing && mPlayer.isPlaying()) { msg = obtainMessage(SHOW_PROGRESS); sendMessageDelayed(msg, 1000 - (pos % 1000)); } break; } } }; private String stringForTime(int timeMs) { int totalSeconds = timeMs / 1000; int seconds = totalSeconds % 60; int minutes = (totalSeconds / 60) % 60; int hours = totalSeconds / 3600; mFormatBuilder.setLength(0); if (hours > 0) { return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds) .toString(); } else { return mFormatter.format("%02d:%02d", minutes, seconds).toString(); } } private int setProgress() { DebugTools.d("control2 setProgress"); if (mPlayer == null || mDragging) { return 0; } int position = mPlayer.getCurrentPosition(); int duration = mPlayer.getDuration(); DebugTools.d("control2 setProgress position: " + position + " duration: " + duration); if (mProgress != null) { if (duration > 0) { // use long to avoid overflow long pos = 1000L * position / duration; mProgress.setProgress((int) pos); } int percent = mPlayer.getBufferPercentage(); mProgress.setSecondaryProgress(percent * 10); } if (mEndTime != null) mEndTime.setText(stringForTime(duration)); if (mCurrentTime != null) mCurrentTime.setText(stringForTime(position)); return position; } @Override public boolean onTouchEvent(MotionEvent event) { show(sDefaultTimeout); return true; } @Override public boolean onTrackballEvent(MotionEvent ev) { show(sDefaultTimeout); return false; } @Override public boolean dispatchKeyEvent(KeyEvent event) { int keyCode = event.getKeyCode(); final boolean uniqueDown = event.getRepeatCount() == 0 && event.getAction() == KeyEvent.ACTION_DOWN; if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE) { if (uniqueDown) { doPauseResume(); show(sDefaultTimeout); if (mPauseButton != null) { mPauseButton.requestFocus(); } } return true; } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) { if (uniqueDown && !mPlayer.isPlaying()) { mPlayer.start(); updatePausePlay(); show(sDefaultTimeout); } return true; } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) { if (uniqueDown && mPlayer.isPlaying()) { mPlayer.pause(); updatePausePlay(); show(sDefaultTimeout); } return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE || keyCode == KeyEvent.KEYCODE_CAMERA) { // don't show the controls for volume adjustment return super.dispatchKeyEvent(event); } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) { if (uniqueDown) { hide(); } return true; } show(sDefaultTimeout); return super.dispatchKeyEvent(event); } private OnClickListener mPauseListener = new OnClickListener() { public void onClick(View v) { doPauseResume(); show(sDefaultTimeout); } }; private OnClickListener mShareListener = new OnClickListener() { public void onClick(View v) { if(mMediaControlListener != null){ // mMediaControlListener.onClickShare(v); } } }; public void setMediaControlListener(MediaControlListener listener){ mMediaControlListener = listener; } private void updatePausePlay() { if (mRoot == null || mPauseButton == null) return; // if (mPlayer.isPlaying()) { // mPauseButton.setImageResource(R.drawable.mediacontroller_pause); //// mPauseButton.setImageResource(com.android.internal.R.drawable.ic_media_pause); // } else { // mPauseButton.setImageResource(R.drawable.mediacontroller_play); //// mPauseButton.setImageResource(com.android.internal.R.drawable.ic_media_play); // } } public void doPause(){ if (mPlayer.isPlaying()) { mPlayer.pause(); mPauseButton.setImageResource(R.mipmap.library_video_mediacontroller_play); if(mMediaControlListener != null){ mMediaControlListener.onClickPause(); } } } public void doPauseResume() { if (mPlayer.isPlaying()) { mPlayer.pause(); mPauseButton.setImageResource(R.mipmap.library_video_mediacontroller_play); if(mMediaControlListener != null){ mMediaControlListener.onClickPause(); } } else { mPlayer.start(); mPauseButton.setImageResource(R.mipmap.library_video_mediacontroller_pause); if(mMediaControlListener != null){ mMediaControlListener.onClickStart(); } } // updatePausePlay(); } // There are two scenarios that can trigger the seekbar listener to trigger: // // The first is the user using the touchpad to adjust the posititon of the // seekbar's thumb. In this case onStartTrackingTouch is called followed by // a number of onProgressChanged notifications, concluded by // onStopTrackingTouch. // We're setting the field "mDragging" to true for the duration of the // dragging // session to avoid jumps in the position in case of ongoing playback. // // The second scenario involves the user operating the scroll ball, in this // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch // notifications, // we will simply apply the updated position without suspending regular // updates. private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { public void onStartTrackingTouch(SeekBar bar) { show(3600000); mDragging = true; // By removing these pending progress messages we make sure // that a) we won't update the progress while the user adjusts // the seekbar and b) once the user is done dragging the thumb // we will post one of these messages to the queue again and // this ensures that there will be exactly one message queued up. mHandler.removeMessages(SHOW_PROGRESS); if(mAdditionalSeekListener != null){ mAdditionalSeekListener.onStartTrackingTouch(bar); } } public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { if (!fromuser) { // We're not interested in programmatically generated changes to // the progress bar's position. return; } long duration = mPlayer.getDuration(); long newposition = (duration * progress) / 1000L; mPlayer.seekTo((int) newposition); if (mCurrentTime != null) mCurrentTime.setText(stringForTime((int) newposition)); if(mAdditionalSeekListener != null){ mAdditionalSeekListener.onProgressChanged(bar, progress, fromuser); } } public void onStopTrackingTouch(SeekBar bar) { mDragging = false; setProgress(); updatePausePlay(); show(sDefaultTimeout); // Ensure that progress is properly updated in the future, // the call to show() does not guarantee this because it is a // no-op if we are already showing. mHandler.sendEmptyMessage(SHOW_PROGRESS); if(mAdditionalSeekListener != null){ mAdditionalSeekListener.onStopTrackingTouch(bar); } } }; private OnSeekBarChangeListener mAdditionalSeekListener; public void setAdditionalSeekBarListener(OnSeekBarChangeListener listener){ mAdditionalSeekListener = listener; } @Override public void setEnabled(boolean enabled) { if (mPauseButton != null) { mPauseButton.setEnabled(enabled); } if (mFfwdButton != null) { mFfwdButton.setEnabled(enabled); } if (mRewButton != null) { mRewButton.setEnabled(enabled); } if (mNextButton != null) { mNextButton.setEnabled(enabled && mNextListener != null); } if (mPrevButton != null) { mPrevButton.setEnabled(enabled && mPrevListener != null); } if (mProgress != null) { mProgress.setEnabled(enabled); } disableUnsupportedButtons(); super.setEnabled(enabled); } @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(MediaController.class.getName()); } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(MediaController.class.getName()); } private OnClickListener mRewListener = new OnClickListener() { public void onClick(View v) { int pos = mPlayer.getCurrentPosition(); pos -= 5000; // milliseconds mPlayer.seekTo(pos); setProgress(); show(sDefaultTimeout); } }; private OnClickListener mFfwdListener = new OnClickListener() { public void onClick(View v) { int pos = mPlayer.getCurrentPosition(); pos += 15000; // milliseconds mPlayer.seekTo(pos); setProgress(); show(sDefaultTimeout); } }; public void seekTo(int pos){ mPlayer.seekTo(pos); setProgress(); show(sDefaultTimeout); } private void installPrevNextListeners() { if (mNextButton != null) { mNextButton.setOnClickListener(mNextListener); mNextButton.setEnabled(mNextListener != null); } if (mPrevButton != null) { mPrevButton.setOnClickListener(mPrevListener); mPrevButton.setEnabled(mPrevListener != null); } } public void setPrevNextListeners(OnClickListener next, OnClickListener prev) { mNextListener = next; mPrevListener = prev; mListenersSet = true; if (mRoot != null) { installPrevNextListeners(); if (mNextButton != null && !mFromXml) { mNextButton.setVisibility(View.VISIBLE); } if (mPrevButton != null && !mFromXml) { mPrevButton.setVisibility(View.VISIBLE); } } } }
源码地址:http://download.csdn.net/detail/paddyy/9414789
相关文章推荐
- Android开发中遇到的问题(一)——自定义videoview设置视频大小,实现上下黑边
- Android中Fragment使用VideoView会出现只有声音没有图像的问题
- 打造私人在线视频播放器,就是这么简单................
- android视频播放(VideoView和MediaController)
- Add SurfaceView flash a black screen(动态添加SurfaceView导致黑一下屏)
- 关于Android VideoView seekTo不准确的问题
- Android中播放MP4文件
- Android - 标准VideoView播放示例
- Android视频播放(一)
- Android 视频播放的三种方法
- Android 播放视频的四种方法
- getDuration()获取媒体总长度值为-1
- Android 实战 - 个人App乐逗项目(查看网页链接封装,播放视频封装)
- 关于VideoView无法监听视频播放时缓冲或者卡顿状态的解决办法
- Vitamio使用总结
- android Videoview 缓冲图标显示和进度条更新
- android 两个放置VideoView的Actitity来回切换BUG
- 安卓飞机大战(八) 添加视频文件
- Android Video简述
- Android学习——使用videoView 来播放视频