项目中有个需求:当用户长按某个键,当有5秒的时候,提示用户松手。需求非常简单,如何用简单高效的方法来实现呢?
刚开始是打算用个计时器,如果计时达到了5s,就提示用户松手,后面回想android button的长按点击事件,它又是如何实现的呢?
view 的长按点击事件部分源码:
//这是一个runnable
private CheckForLongPress mPendingCheckForLongPress;
private final class CheckForLongPress implements Runnable {
private int mOriginalWindowAttachCount;
private float mX;
private float mY;
@Override
public void run() {
if (isPressed() && (mParent != null)
&& mOriginalWindowAttachCount == mWindowAttachCount) {
if (performLongClick(mX, mY)) {
mHasPerformedLongPress = true;
}
}
}
public void setAnchor(float x, float y) {
mX = x;
mY = y;
}
public void rememberWindowAttachCount() {
mOriginalWindowAttachCount = mWindowAttachCount;
}
}
//初始化的地方:
private void checkForLongClick(int delayOffset, float x, float y) {
if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress == null) {
mPendingCheckForLongPress = new CheckForLongPress();
}
mPendingCheckForLongPress.setAnchor(x, y);
mPendingCheckForLongPress.rememberWindowAttachCount();
//关键是这个postDelay:500ms之后,执行runnable
postDelayed(mPendingCheckForLongPress,
ViewConfiguration.getLongPressTimeout() - delayOffset);
}
}
从上面源码中推断出:当用户按下的时候,过500ms post 一个runnable, 如果在500ms的时候,用户一直都是没有松手的状态,那么就设置longclicklistener,否则就不是长按事件。当然源码比这个复杂,但是大致思路是这样的,同理,我们也仿照这个流程来做:
public class LongPressActivity extends Activity implements View.OnTouchListener{
private Button mButton;
private CheckForLongPress1 mCheckForLongPress1;
private volatile boolean isLongPressed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_long_press);
mButton = (Button) findViewById(R.id.btn_long);
mCheckForLongPress1 = new CheckForLongPress1();
mButton.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("hxy","action down");
isLongPressed = true;
mButton.postDelayed(mCheckForLongPress1,5000);
break;
case MotionEvent.ACTION_MOVE:
isLongPressed = true;
break;
case MotionEvent.ACTION_UP:
isLongPressed = false;
Log.d("hxy","action up");
break;
}
return super.onTouchEvent(event);
}
private class CheckForLongPress1 implements Runnable{
@Override
public void run() {
//5s之后,查看isLongPressed的变量值:
if(isLongPressed){//没有做up事件
Log.d("hxy","5s的事件触发");
}else{
mButton.removeCallbacks(mCheckForLongPress1);
}
}
}
}