# movePlayer **Repository Path**: osby/movePlayer ## Basic Information - **Project Name**: movePlayer - **Description**: 视频播放器 - **Primary Language**: Android - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-06-10 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # movePlayer 首次开启App进入`SplashActivity`, 点击页面快速进入`MainActivity`(默认等待2秒后进入). ### 问题描述: 1. 用户点击了`SplashActivity`进入`MainActivity`后(在等待期内)立即退出, 会自动再次打开`MainActivity` 2. 用户点击了`SplashActivity`进入`MainActivity`, 默认进入的代码任然会再次打开一次`MainActivity` 3. 用户多次点击`SplashActivity`, 会多次打开`MainActivity` ### 解决方案 调用`finish()`关闭启动页面, 并在`onDestroy()`中取消未执行的消息 ```java public class SplashActivity extends Activity { private Handler handler = new Handler(); // 保证主界面只打开一次 private boolean isStartMain = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); // 等待两秒后执行 // runnable.run() 方法执行在主线程 handler.postDelayed(new Runnable() { public void run() { startMainActivity(); } }, 2000); } // 开启主界面 private void startMainActivity() { if (!isStartMain) { isStartMain = true; Intent intent = new Intent(SplashActivity.this, MainActivity.class); startActivity(intent); // 关闭启动页面 finish(); } } @Override public boolean onTouchEvent(MotionEvent event) { // 点击启动页面, 快速进入到主页面 startMainActivity(); return super.onTouchEvent(event); } @Override protected void onDestroy() { super.onDestroy(); // 取消打开MainActivity的意图 handler.removeCallbacksAndMessages(null); } } ``` # Activity声明周期 ## 打开 -> 关闭 (一个Activity) ``` Enter : onCreate() -> onStart() -> onResume() >> Home : onPause() -> onStop() Home >> : onRestart() -> onStart() onResume() Back : onPause() -> onStop() -> onDestroy() ``` ## A -> B(返回) -> A 【B完全覆盖A】 ``` Enter A : A.onCreate() -> A.onStart() -> A.onResume() A >> B : A.onPause() -> B.onCreate() -> B.onStart() -> B.onResume() -> A.onStop() B >> A : B.onPause() -> A.onRestart() -> A.onStart() -> A.onResume() -> B.onDestroy() ``` ## A -> B(返回) -> A 【B不完全覆盖A】 ``` Enter A : A.onCreate() -> A.onStart() -> A.onResume() // 没有 A.onStop() A >> B : A.onPause() -> B.onCreate() -> B.onStart() -> B.onResume() // 没有 A.onStart() , A.onRestart() B >> A : B.onPause() -> A.onResume() -> B.onStopp() -> B.onDestroy() ``` ## 横竖屏切换 ``` onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResume() ``` 配置哪些改变不执行生命周期方法 ```xml ``` # 手势识别器 ``` // 1. 声明 // 定义手势识别器 private GestureDetector detector; // 2. 创建实例并监听关心的事件 // 实例化手势识别器 detector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { // 长按 @Override public void onLongPress(MotionEvent e) { switchPlayOrPause(); } // 单击 @Override public boolean onSingleTapConfirmed(MotionEvent e) { // Toast.makeText(SystemVideoPlayer.this, "点击", Toast.LENGTH_SHORT).show(); showMediaController(!isShowMediaController); return true; } }); // 3. 关联触摸事件 @Override public boolean onTouchEvent(MotionEvent event) { // 把事件传递给手势识别器 detector.onTouchEvent(event); return super.onTouchEvent(event); } ``` ## 滑动屏幕改变音量 在 `onTouchEvent()` 中计算逻辑: 1. 按下时计算初始化值 需要记录数据, 并移除延迟发送的(HIDE_CONTROLLER)消息 - startY: 手指按下时Y坐标 - rangeY: 可滑动的区域总量 - currVolume: 滑动结束时当前音量 - maxVolume: 最大音量 2. 滑动时修改音量 - endY: 滑动结束时Y坐标 - changedVolume: 修改的音量 - finalVolume: 最终的设备音量 3. 手指离开时延迟发送隐藏控制面板(HIDE_CONTROLLER) 计算公式: (startY - endY) / rangeY = changedVolume / maxVolume; finalVolume = min(max(currVolume + changedVolume, 0), maxVolume); ``` private void touchScreenChangeVolume(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下 touchStartY = event.getY(); touchRangeY = Math.min(screenHeight, screenWidth); touchCurrVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 移除隐藏控制面板消息 handler.removeMessages(HIDE_CONTROLLER); break; case MotionEvent.ACTION_MOVE: // 滑动 float moveEndY = event.getY(); float changeDistance = (touchStartY - moveEndY); float changeVolume = changeDistance / touchRangeY * maxVolume; if (0 != changeVolume) { float finalVolume = Math.min(Math.max(0, changeVolume + touchCurrVolume), maxVolume); updateVolume((int) finalVolume); } break; case MotionEvent.ACTION_UP: // 离开 // 延迟发送隐藏控制面板消息 handler.sendEmptyMessageDelayed(HIDE_CONTROLLER, HIDE_CONTROLLER_DELAY_TIME); break; } } ```