在滚动时使android listview可单击

时间:2014-06-04 10:46:17

标签: android listview android-listview scroll

即使ListView当前正在滚动,有没有办法让ListView的{​​{1}}对触摸作出反应?

滚动ListView的默认行为似乎只是在触摸时停止滚动。

我希望它在滚动时可点击的原因是:我有一个ListView,它会自动永久滚动,并且应该允许交互anwyway。自动滚动就像这样实现:

onItemClickListener

即使此线程正在运行,也可以触发ListView的onTouchListener。我在scrollThread = new Thread() { public void run() { listView.post(new Runnable() { @Override public void run() { listView.smoothScrollBy(5, 0); } }); try {Thread.sleep(100);} catch (InterruptedException ignore) {} } } 返回false,以免消耗触摸事件。但是只有在我通过中断线程来停止滚动时才能触发onItemClickListener。

手动转发ListView的onTouch事件是避免这种情况的唯一方法吗?如果是这样,检测项目的最佳方法是什么"下面" onTouch事件?

1 个答案:

答案 0 :(得分:0)

我发现手动转发触摸效果很好。我删除了默认的onItemClickListener,并在我的onTouch方法中调整了Jake Wharton’s SwipeDismissListViewTouchListener中的一些自定义子视图点击检测代码,如下所示。

知道是否有一种简单的方法可以通过默认的onItemClickListener使滚动列表视图注册项目点击,这仍然很有趣。

public boolean onTouch(View v, MotionEvent event)
{
    detectItemClick((ListView)v, event);
    // ...
}

private float mDownX;
private float mDownY;
private boolean isClick;

private void detectItemClick(ListView listView, MotionEvent event)
{
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            mDownX = event.getX();
            mDownY = event.getY();
            isClick = true;
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            if (isClick) {
                // Find the item view that was touched (perform a hit test)
                Rect rect = new Rect();
                int childCount = listView.getChildCount();
                int[] listViewCoords = new int[2];
                listView.getLocationOnScreen(listViewCoords);
                int x = (int) event.getRawX() - listViewCoords[0];
                int y = (int) event.getRawY() - listViewCoords[1];
                View child;
                for (int i = 0; i < childCount; i++) {
                    child = listView.getChildAt(i);
                    if (child == null) return;
                    child.getHitRect(rect);
                    if (rect.contains(x, y)) {
                        int position = listView.getPositionForView(child);
                        onItemClick(listView, child, position, 0);
                        break;
                    }
                }
            }
            break;
        case MotionEvent.ACTION_MOVE:
            final float SCROLL_THRESHOLD = 10;
            if (isClick && (Math.abs(mDownX - event.getX()) > SCROLL_THRESHOLD
                   || Math.abs(mDownY - event.getY()) > SCROLL_THRESHOLD)) {
                isClick = false;
            }
            break;
        default:
            break;
    }
}