我遇到了同样的问题,但在这里没有找到答案。
我想检测 ListView 项中的滑动操作并将其标记为已滑动,同时继续支持 OnItemClick 和 OnItemLongClick。
这是我的解决方案:
第一个 SwipeDetector 类:
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SwipeDetector implements View.OnTouchListener {
public static enum Action {
LR, // Left to Right
RL, // Right to Left
TB, // Top to bottom
BT, // Bottom to Top
None // when no action was detected
}
private static final String logTag = "SwipeDetector";
private static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
private Action mSwipeDetected = Action.None;
public boolean swipeDetected() {
return mSwipeDetected != Action.None;
}
public Action getAction() {
return mSwipeDetected;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
mSwipeDetected = Action.None;
return false; // allow other events like Click to be processed
case MotionEvent.ACTION_UP:
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// horizontal swipe detection
if (Math.abs(deltaX) > MIN_DISTANCE) {
// left or right
if (deltaX < 0) {
Log.i(logTag, "Swipe Left to Right");
mSwipeDetected = Action.LR;
return false;
}
if (deltaX > 0) {
Log.i(logTag, "Swipe Right to Left");
mSwipeDetected = Action.RL;
return false;
}
} else if (Math.abs(deltaY) > MIN_DISTANCE) { // vertical swipe
// detection
// top or down
if (deltaY < 0) {
Log.i(logTag, "Swipe Top to Bottom");
mSwipeDetected = Action.TB;
return false;
}
if (deltaY > 0) {
Log.i(logTag, "Swipe Bottom to Top");
mSwipeDetected = Action.BT;
return false;
}
}
return false;
}
return false;
}
}
第二个我在列表视图中使用滑动检测器类:
final ListView lv = getListView();
final SwipeDetector swipeDetector = new SwipeDetector();
lv.setOnTouchListener(swipeDetector);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (swipeDetector.swipeDetected()){
// do the onSwipe action
} else {
// do the onItemClick action
}
}
});
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
if (swipeDetector.swipeDetected()){
// do the onSwipe action
} else {
// do the onItemLongClick action
}
}
});
这样我可以支持 3 种操作 - 滑动、单击、长按,并且我可以使用 ListView 项目信息。
稍后添加:
由于 ListView 捕捉到滚动动作,因此有时很难滑动。为了解决这个问题,我对 SwipeDetector.onTouch 进行了以下更改:
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
mSwipeDetected = Action.None;
return false; // allow other events like Click to be processed
}
case MotionEvent.ACTION_MOVE: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// horizontal swipe detection
if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE) {
// left or right
if (deltaX < 0) {
Log.i(logTag, "Swipe Left to Right");
mSwipeDetected = Action.LR;
return true;
}
if (deltaX > 0) {
Log.i(logTag, "Swipe Right to Left");
mSwipeDetected = Action.RL;
return true;
}
} else
// vertical swipe detection
if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE) {
// top or down
if (deltaY < 0) {
Log.i(logTag, "Swipe Top to Bottom");
mSwipeDetected = Action.TB;
return false;
}
if (deltaY > 0) {
Log.i(logTag, "Swipe Bottom to Top");
mSwipeDetected = Action.BT;
return false;
}
}
return true;
}
}
return false;
}