这是我的 old question .不过这次我也提供了我的代码。
我有一个包含不同类型行的 ListView。该行可能包含文本、图像、视频或其他内容。如果我单击 ImageView(行内),我将转到另一个 Activity 以全屏显示图像,如果我单击视频(行内),我将转到另一个 Activity 以播放他的视频。
我已经在我的 ListView 上实现了从右到左滑动监听器。如果我从 ListView 中的空白区域开始 ListView 滑动,则滑动有效(下图中的第一行和第二行)。但是,如果我从 ListView 行的项目开始 ListView 滑动,则滑动不起作用(下图中的第三行和第四行)。如果我从 ImageView 和 Video 中删除点击事件,那么即使我从 ListView 行的项目开始滑动,滑动也会起作用,即在这种情况下,无论我在哪一行进行滑动,滑动都适用于整个 ListView。
我怎样才能摆脱这个问题?我认为如果我禁用 ListView 中所有项目的所有点击事件,就可以实现这一点。怎么能这样呢?还有其他办法吗?
我想同时在 ListView 上滑动并单击 ListView 的项目。
SwipeDetector.java - 用于检测 ListView 上的滑动
public class SwipeDetector implements View.OnTouchListener {
private SwipeListener swipeListener;
private ListView mListView;
private int hundred;
private boolean motionInterceptDisallowed = false;
public static enum Action {
LR, // Left to right
RL, // Right to left
TB, // Top to bottom
BT, // Bottom to top
None // Action not found
}
private static final int HORIZONTAL_MIN_DISTANCE = 30; // The minimum
// distance for
// horizontal swipe
private static final int VERTICAL_MIN_DISTANCE = 80; // The minimum distance
// for vertical
// swipe
private float downX, downY, upX, upY; // Coordinates
private Action mSwipeDetected = Action.None; // Last action
public SwipeDetector(Context context, ListView listView) {
hundred = (int) context.getResources().getDimension(R.dimen.hundred);
mListView = listView;
}
public boolean swipeDetected() {
return mSwipeDetected != Action.None;
}
public Action getAction() {
return mSwipeDetected;
}
/**
* Swipe detection
*/@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_MOVE:
{
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
float absX = Math.abs(deltaX);
float absY = Math.abs(deltaY);
if((absX >= (3 * absY)) && absX > HORIZONTAL_MIN_DISTANCE && mListView != null && !motionInterceptDisallowed) {
mListView.requestDisallowInterceptTouchEvent(true);
motionInterceptDisallowed = true;
}
if((absX >= (3 * absY)) && absX <= hundred) {
if (deltaX > 0) {
mSwipeDetected = Action.RL;
swipeListener.onSwipe(MotionEvent.ACTION_MOVE, Action.RL, absX);
}
}
return false;
}
case MotionEvent.ACTION_UP:
swipeListener.onSwipe(MotionEvent.ACTION_UP, Action.BT, 0);
if (mListView != null) {
mListView.requestDisallowInterceptTouchEvent(false);
motionInterceptDisallowed = false;
}
return false;
case MotionEvent.ACTION_CANCEL:
return true;
}
return false;
}
/**
* Set chat send listener
* @param listener
*/
public void setSwipeListener(SwipeListener listener) {
swipeListener = listener;
}
public interface SwipeListener {
void onSwipe(int event, Action action, float x);
}
}
这就是我在 ListView 上设置 SwipeDetector 的方式
final SwipeDetector swipeDetector = new SwipeDetector(SwipeActivity.this, mListView);
swipeDetector.setSwipeListener(mSwipeListener);
mListView.setOnTouchListener(swipeDetector);
我的 Activity 实现了 SwipeDetector.SwipeListener
下面重写了 onSwipe() 方法
@Override
public void onSwipe(int event, SwipeDetector.Action action, float x) {
switch (event) {
case MotionEvent.ACTION_MOVE:
System.out.println("list move");
break;
case MotionEvent.ACTION_UP:
System.out.println("list up");
break;
}
}
在我的适配器中,我在我的 TextView、ImageView 和 VideoView 上设置了 onClickListener()
holder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("item textview click");
}
});
holder.mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("item imageview click");
}
});
holder.mVideoView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("item videoview click");
}
});
当我从 ListView 的空白区域开始滑动时,ListView 的滑动监听器会捕获它。但是,当我从 TextView/ImageView/VideoView 开始滑动时,View 的 onClickListener 被触发,而不是父级(ListView 的)onTouchListener()。
我该如何实现?我希望当我点击 ListView 的项目时应该触发该项目的 onClick,当我在 ListView 的项目上滑动时应该触发 ListView 的 onSwipe。
最佳答案
listitem
的 onClickListener
和 List
的 SwipeListener
是不可能的,因为它在两者之间产生歧义触摸查看以考虑
您使用实现了 onTouchListener
的 OnSwipeTouchListener
OnSwipeTouchListener.java
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class OnSwipeTouchListener implements OnTouchListener {
private final GestureDetector gestureDetector;
public OnSwipeTouchListener (Context ctx){
gestureDetector = new GestureDetector(ctx, new GestureListener());
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
result = true;
}
else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
}
result = true;
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public void onSwipeRight() {
}
public void onSwipeLeft() {
}
public void onSwipeTop() {
}
public void onSwipeBottom() {
}
}
并在 listitem
上使用 OnSwipeTouchListener
listitem.setOnTouchListener(new OnSwipeTouchListener() {
public void onSwipeLeft() {
//stuff to do list view left swipe
Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
}
public boolean onTouch(View v, MotionEvent event) {
//stuff to do on list item click
return gestureDetector.onTouchEvent(event);
}
});
}); //to get click events
关于android - ListView 上的 SwipeListener 和 ListView 项目上的 ClickListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32866357/