android – 如何用双短连续按键实现Button?
作者:互联网
我正在创建一个MP3播放器并想要一个双下一首歌曲/快进按钮.因此,如果按下此按钮,它将继续播放到下一首歌曲,如果按下该按钮,它将快进到当前歌曲.
我可以使用OnClickListener使下一首歌工作…
private OnClickListener mSkipForwardListener = new OnClickListener() {
public void onClick(View v)
{
mPlayerService.forwardASong();
}
};
…但我如何获得快进功能?我尝试过OnLongClickListener,但只触发一次.
private OnLongClickListener mFastForwardListener = new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mPlayerService.fastForward();
return true;
}
};
并且onTouch似乎只在key.down和key.up上触发一次.
private OnTouchListener mFastForwardListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mPlayerService.fastForward();
return true;
}
};
任何帮助,非常感谢,
M.
解决方法:
通过从onTouch返回true,您正在使用触摸事件,因此您的按钮甚至看不到它.不再发生触摸事件的原因是没有View实际处理了down事件.
因此,您需要在侦听器中从onTouch返回false. (并希望底层视图保持返回true,因为如果在这种情况下View – 按钮 – 从onTouchEvent返回false,那么也不会再向侦听器发送事件 – 对于一个按钮,这很好,但对于其他视图覆盖onTouchEvent而不是使用监听器来获得更多控制和可靠性).
类似下面的OnTouchListener应该是大致正确的(这将需要是一个Activity的内部类,并且不要设置OnClickListener,因为它也将被调用!):
private abstract class LongTouchActionListener implements OnTouchListener {
/**
* Implement these methods in classes that extend this
*/
public abstract void onClick(View v);
public abstract void onLongTouchAction(View v);
/**
* The time before we count the current touch as
* a long touch
*/
public static final long LONG_TOUCH_TIME = 500;
/**
* The interval before calling another action when the
* users finger is held down
*/
public static final long LONG_TOUCH_ACTION_INTERVAL = 100;
/**
* The time the user first put their finger down
*/
private long mTouchDownTime;
/**
* The coordinates of the first touch
*/
private float mTouchDownX;
private float mTouchDownY;
/**
* The amount the users finger has to move in DIPs
* before we cancel the touch event
*/
public static final int TOUCH_MOVE_LIMIT_DP = 50;
/**
* TOUCH_MOVE_LIMIT_DP converted to pixels, and squared
*/
private float mTouchMoveLimitPxSq;
/**
* Is the current touch event a long touch event
*/
private boolean mIsLongTouch;
/**
* Is the current touch event a simple quick tap (click)
*/
private boolean mIsClick;
/**
* Handlers to post UI events
*/
private LongTouchHandler mHandler;
/**
* Reference to the long-touched view
*/
private View mLongTouchView;
/**
* Constructor
*/
public LongTouchActionListener(Context context) {
final float scale = context.getResources().getDisplayMetrics().density;
mTouchMoveLimitPxSq = scale*scale*TOUCH_MOVE_LIMIT_DP*TOUCH_MOVE_LIMIT_DP;
mHandler = new LongTouchHandler();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// down event
mIsLongTouch = false;
mIsClick = true;
mTouchDownX = event.getX();
mTouchDownY = event.getY();
mTouchDownTime = event.getEventTime();
mLongTouchView = view;
// post a runnable
mHandler.setEmptyMessageDelayed(LongTouchHandler.MESSAGE_LONG_TOUCH_WAIT, LONG_TOUCH_TIME);
break;
case MotionEvent.ACTION_MOVE:
// check to see if the user has moved their
// finger too far
if (mIsClick || mIsLongTouch) {
final float xDist = (event.getX() - mTouchDownX);
final float yDist = (event.getY() - mTouchDownY);
final float distanceSq = (xDist*xDist) + (yDist*yDist);
if (distanceSq > mTouchMoveLimitSqPx) {
// cancel the current operation
mHandler.removeMessages(LongTouchHandler.MESSAGE_LONG_TOUCH_WAIT);
mHandler.removeMessages(LongTouchHandler.MESSAGE_LONG_TOUCH_ACTION);
mIsClick = false;
mIsLongTouch = false;
}
}
break;
case MotionEvent.ACTION_CANCEL:
mIsClick = false;
case MotionEvent.ACTION_UP:
// cancel any message
mHandler.removeMessages(LongTouchHandler.MESSAGE_LONG_TOUCH_WAIT);
mHandler.removeMessages(LongTouchHandler.MESSAGE_LONG_TOUCH_ACTION);
long elapsedTime = event.getEventTime() - mTouchDownTime;
if (mIsClick && elapsedTime < LONG_TOUCH_TIME) {
onClick(v);
}
break;
}
// we did not consume the event, pass it on
// to the button
return false;
}
/**
* Handler to run actions on UI thread
*/
private class LongTouchHandler extends Handler {
public static final int MESSAGE_LONG_TOUCH_WAIT = 1;
public static final int MESSAGE_LONG_TOUCH_ACTION = 2;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_LONG_TOUCH_WAIT:
mIsLongTouch = true;
mIsClick = false;
// flow into next case
case MESSAGE_LONG_TOUCH_ACTION:
if (!mIsLongTouch) return;
onLongTouchAction(mLongTouchView); // call users function
// wait for a bit then update
takeNapThenUpdate();
break;
}
}
private void takeNapThenUpdate() {
sendEmptyMessageDelayed(MESSAGE_LONG_TOUCH_ACTION, LONG_TOUCH_ACTION_INTERVAL);
}
};
};
这是一个实现的例子
private class FastForwardTouchListener extends LongTouchActionListener {
public void onClick(View v) {
// Next track
}
public void onLongTouchAction(View v) {
// Fast forward the amount of time
// between long touch action calls
mPlayer.seekTo(mPlayer.getCurrentPosition() + LONG_TOUCH_ACTION_INTERVAL);
}
}
标签:android,button,onclick,ontouchlistener 来源: https://codeday.me/bug/20190610/1210925.html