gpt4 book ai didi

android - 如何实现双短按和长按的Button?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:07:09 24 4
gpt4 key购买 nike

我正在创建一个 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;
}
};

任何帮助,非常感谢,

最佳答案

通过从 onTouch 返回 true,您正在使用触摸事件,因此您的按钮甚至看不到它。不再发生触摸事件的原因是没有 View 实际处理了按下事件。

因此您需要在监听器中从 onTouch 返回 false。 (并希望底层 View 继续返回 true,因为如果 View - 在这种情况下的按钮 - 从它的 onTouchEvent 返回 false,那么也不会再有事件发送给您的监听器- 对于一个按钮,这很好,但对于其他 View ,覆盖 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?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5917909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com