我想要水平滑动手势来控制媒体播放器搜索,如 mx 播放器。我尝试过手势检测器,但没有像 mx 播放器那样工作。任何形式的帮助将不胜感激。
这是带有手势检测器和缩放手势检测器的类。使用手势检测器水平滚动,我无法获得响应滚动。
public class OnSwipeTouchListener implements View.OnTouchListener {
private static final int SWIPE_THRESHOLD = 60;//threshold of swipe
public static final int SWIPE_LEFT = 1;
public static final int SWIPE_RIGHT = 2;
private final GestureDetector gestureDetector;
ScaleGestureDetector mgesturedetector;
Context context;
private boolean isSingleTouch;
private float width, height = 0;
private float scale = 1.0f;
private float minScale = 0.8f;
private float maxScale = 4.0f;
int amount = 0;
public OnSwipeTouchListener(Context ctx) {
gestureDetector = new GestureDetector(ctx, new GestureListener(ctx));
mgesturedetector = new ScaleGestureDetector(ctx , new ScaleListener(ctx));
this.context = ctx;
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(motionEvent.getPointerCount()>1)
{
mgesturedetector.onTouchEvent(motionEvent);
}
else
{
gestureDetector.onTouchEvent(motionEvent);
}
ontouch(view,motionEvent);
return true;
}
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
private Context mContext;
public ScaleListener(Context context) {
this.mContext = context;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
onscalebegin();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
onscalend(scale);
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
scale *= detector.getScaleFactor();
scale = (scale < 0.8f ? 0.8f : scale); // prevent our view from becoming too small //
scale = ((float)((int)(scale * 100))) / 100;
onscale(scale);
return true;
}
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 60;
private Context context;
public GestureListener(Context context) {
this.context = context;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
ondoubletap();
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
onsingleTapConfirmed();
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float deltaX = e1.getRawX() - e2.getRawX();
float deltaY = e1.getRawY() - e2.getRawY();
if (Math.abs(deltaY) > SWIPE_THRESHOLD) {
if (e1.getX() < getDeviceWidth(context) /2) {//left edge
onVerticalScroll(deltaY / getDeviceHeight(context), SWIPE_LEFT);
} else if (e1.getX() > getDeviceWidth(context) /2) {//right edge
onVerticalScroll(deltaY / getDeviceHeight(context), SWIPE_RIGHT);
}
}
return true;
}
}
void onsingleTapConfirmed(){}
boolean ontouch(View view, MotionEvent event){
return false;
}
void ondoubletap(){}
public void onHorizontalScrollRight(float percent) {}
public void onHorizontalScrollLeft() {}
void onVerticalScroll(float percent, int direction){}
void onscale(Float scale){}
void onscalebegin(){}
void onscalend(float scale){}
void onscroll(float x , float y){}
void onscrollend(){}
}
this is the MediaPlayerActivity code in which above class is implemented:
view.setOnTouchListener(new OnSwipeTouchListener(this){
@Override
void onscalebegin() {
isScrolling = true;
}
@Override
void onscalend(float scale) {
isScrolling = false;
scale2 = scale;
}
@Override
void onscale(Float scale) {
onScale(scale);
}
@Override
boolean ontouch(View view,MotionEvent event) {
int action = (MotionEventCompat.getActionMasked(event) );
float currentX = 0.0f;
float currentY = 0.0f;
float current_diffX = 0.0f;
float current_diffY = 0.0f;
boolean result = false;
if (event.getPointerCount() > 1) {
isScrolling = true;
}
switch (action ) {
case MotionEvent.ACTION_UP:
mCurVolume = -1;
mCurBrightness = -1;
mCenterLayout.setVisibility(GONE);
brightnesswrapper.setVisibility(GONE);
volumewrapper.setVisibility(GONE);
isScrolling = false;
verticalscroll = false;
horizontalscroll = false;
result =true;
break;
//
case MotionEvent.ACTION_DOWN: {
if(!isScrolling && !verticalscroll) {
baseX = event.getX();
baseY = event.getY();
}
result = true;
}
break;
////
case MotionEvent.ACTION_MOVE: {
if(!verticalscroll && !isScrolling ) {
if (event.getPressure() > 0.9f) {
// horizontalscroll = true;
currentX = event.getX();
currentY = event.getY();
current_diffX = currentX - baseX;
current_diffY = currentY - baseY;
if (swipe == LEFT_SWIPE) {
if (currentX > previousX) {
//If here, then horizontal swipe has been reversed
swipe = RIGHT_SWIPE;
//Overwrite base coordinate
baseX = previousX;
//Recalculate Difference
current_diffX = currentX - baseX;
} else {
//NOP - Intentionally kept empty
}
} else if (swipe == RIGHT_SWIPE) {
if (currentX < previousX) {
//If here, then horizontal swipe has been reversed
swipe = LEFT_SWIPE;
//Overwrite base coordinate
baseX = previousX;
//Recalculate Difference
current_diffX = currentX - baseX;
} else {
//NOP - Intentionally kept empty
}
} else {
//If here, then it's a fresh swipe event, so compare with base coordinates
if (currentX < baseX) {
swipe = LEFT_SWIPE;
} else if (currentX > baseX) {
swipe = RIGHT_SWIPE;
} else {
//NOP - Intentionally kept empty
}
}
previousX = currentX;
previousY = currentY;
if (Math.abs(current_diffX) > Math.abs(current_diffY)) {
//It's a horizontal swipe
if (Math.abs(current_diffX) > 200f) {
if (current_diffX > 0) {
seekForWard();
horizontalscroll = true;
} else {
seekBackWard();
horizontalscroll = true;
}
}
}
}
}
result = true;
break;
}
default:
result = false;
break;
}
return result;
}
@Override
public void onsingleTapConfirmed() {
if(!isScrolling && !verticalscroll)
{
toggleControllerView();
}
}
@Override
void ondoubletap() {
doPauseResume();
}
}
@Override
void onVerticalScroll(float percent, int direction) {
if (!isScrolling && !horizontalscroll)
{
verticalscroll= true;
if (direction == ViewGestureListener.SWIPE_LEFT) {
mCenterImage.setImageResource(R.drawable.video_bright_bg);
updateBrightness(percent * 2);
} else {
mCenterImage.setImageResource(R.drawable.video_volume_bg);
updateVolume(percent * 2);
}
}
}
private void seekForWard() {
if (mMediaPlayer == null) {
return;
}
int position = mMediaPlayer.getCurrentPosition();
pos += PROGRESS_SEEK ;
mMediaPlayer.seekTo(pos);
setSeekProgress();
}
private void seekBackWard() {
if (mMediaPlayer == null) {
return;
}
int position = mMediaPlayer.getCurrentPosition();
pos -= PROGRESS_SEEK + (1000 * position/mMediaPlayer.getDuration());
mMediaPlayer.seekTo(pos);
setSeekProgress();
}
private int setSeekProgress() {
if (mMediaPlayer == null || mIsDragging) {
return 0;
}
int position = mMediaPlayer.getCurrentPosition();
int duration = mMediaPlayer.getDuration();
if (mSeekBar != null) {
if (duration > 0) {
long pos = 1000L * position / duration;
mSeekBar.setProgress( (int) pos );
}
}
mEndTime.setText(stringToTime(duration));
mCurrentTime.setText(stringToTime(position));
return position;
}
这个类在handlermsg函数的处理程序中使用,以每秒更新seekbar。
我无法解决问题。对于手势检测器的水平滚动,我实现了它,但它不会立即检测到滚动是否反转,它会在手指越过滚动初始化的点时检测到反向滚动。