请实现一个自定义 View 的核心代码,核心要求可以响应如下事件:
// - 要求自定义 View 可以播放一段视频
/ - 在 view 左侧区域上下滑动,可以提高减少音量 /
/ - 在 view 右侧区域上下滑动可以提高减少屏幕亮度
// - 在 view 左右滑动可以快进/快退播放 // - 在 view 区域点击屏幕可以暂停/继续播放
使用 VideoView
实现自定义 View
public class CustomVideoView extends FrameLayout {
private VideoView videoView;
private GestureDetector gestureDetector;
private float initialTouchX, initialTouchY;
private int screenWidth, screenHeight;
private AudioManager audioManager;
private WindowManager.LayoutParams layoutParams;
private float maxVolume;
public CustomVideoView(Context context) {
super(context);
init(context);
}
public CustomVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
// 初始化 VideoView
videoView = new VideoView(context);
addView(videoView, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// 获取屏幕宽高
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
screenHeight = size.y;
// 初始化音频管理器
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
// 获取当前窗口参数以调整亮度
layoutParams = ((Activity) context).getWindow().getAttributes();
// 初始化手势检测器
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (videoView.isPlaying()) {
videoView.pause();
} else {
videoView.start();
}
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
float deltaX = e2.getX() - initialTouchX;
float deltaY = e2.getY() - initialTouchY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// 左右滑动快进/快退
if (deltaX > 0) {
// 快进
videoView.seekTo(videoView.getCurrentPosition() + 10000);
} else {
// 快退
videoView.seekTo(videoView.getCurrentPosition() - 10000);
}
} else {
if (initialTouchX < screenWidth / 2) {
// 左侧区域,上下滑动调整音量
if (deltaY > 0) {
// 降低音量
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
} else {
// 提高音量
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
}
} else {
// 右侧区域,上下滑动调整亮度
if (deltaY > 0) {
// 降低亮度
layoutParams.screenBrightness = Math.max(layoutParams.screenBrightness - 0.1f, 0.1f);
} else {
// 提高亮度
layoutParams.screenBrightness = Math.min(layoutParams.screenBrightness + 0.1f, 1.0f);
}
((Activity) getContext()).getWindow().setAttributes(layoutParams);
}
}
return true;
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
initialTouchX = event.getX();
initialTouchY = event.getY();
return gestureDetector.onTouchEvent(event);
}
public void setVideoPath(String path) {
videoView.setVideoPath(path);
}
public void start() {
videoView.start();
}
public void pause() {
videoView.pause();
}
public boolean isPlaying() {
return videoView.isPlaying();
}
public void seekTo(int millis) {
videoView.seekTo(millis);
}
}
GestureDetector.SimpleOnGestureListener
是 GestureDetector
的一个内部类,提供了各种手势检测回调方法。你可以通过继承 SimpleOnGestureListener
并重写它的方法来定制手势处理逻辑。下面是 SimpleOnGestureListener
内常用方法的详细说明及示例代码。
常用方法及说明
-
onSingleTapUp(MotionEvent e)
- 当用户轻轻点击屏幕后松开时调用。
- 返回
true
表示该事件被处理。 - 示例用途:处理单击事件。
-
onLongPress(MotionEvent e)
- 当用户长按屏幕时调用。
- 示例用途:处理长按事件,如显示上下文菜单。
-
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
- 当用户在屏幕上滑动时调用。
- 参数
e1
表示滑动的起点,e2
表示滑动的终点,distanceX
和distanceY
分别表示滑动的距离。 - 示例用途:处理滚动事件,如滚动列表。
-
onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
- 当用户快速滑动并松开时调用。
- 参数
e1
和e2
表示滑动的起点和终点,velocityX
和velocityY
分别表示滑动的速度。 - 示例用途:处理快速滑动事件,如切换页面。
-
onShowPress(MotionEvent e)
- 当用户按下屏幕但还未松开或拖动时调用。
- 示例用途:处理按压显示效果。
-
onDown(MotionEvent e)
- 当用户按下屏幕时调用。
- 返回
true
表示该事件被处理。 - 示例用途:通常用来初始化一些状态。
-
onDoubleTap(MotionEvent e)
- 当用户双击屏幕时调用。
- 示例用途:处理双击事件,如放大图片。
-
onDoubleTapEvent(MotionEvent e)
- 当双击手势发生的过程中,按下、移动和抬起事件的任何一次调用。
- 示例用途:处理双击过程中的事件。
-
onSingleTapConfirmed(MotionEvent e)
- 当单击事件被确认时调用。
- 示例用途:与
onSingleTapUp
区分,onSingleTapConfirmed
在确定不是双击时调用。