修改SwipeDismissListViewTouchListener以支持滑动或拖动以打开/关闭

时间:2013-12-07 23:15:11

标签: android listview android-listview android-animation

我正在修改以下代码:

https://github.com/romannurik/Android-SwipeToDismiss/blob/master/src/com/example/android/swipedismiss/SwipeDismissListViewTouchListener.java

首先,我只想在触摸指向的任何地方拖动列表视图的子项。但是在应用它之后,似乎我对listview的未来攻击变得搞砸了,我再也无法移动那个孩子了。它就像listview不再正常接收触摸一样,或者感觉列表视图不再接收触摸。

如果我直接修改上面的代码并注释掉从列表视图中删除单元格的方法调用,我会看到类似的行为。以下是我的入门代码:

public class ListItemSwipeListener implements View.OnTouchListener  
{
    private String TAG = "ListItemSwipeListener";
    // Cached ViewConfiguration and system-wide constant values
    private int mSlop;
    private long mAnimationTime;

    private boolean mPaused;
    private boolean mSwiping;

    // Fixed properties
    private ListView mListView;
    private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero

    // Transient properties
    private float mDownX;
    private VelocityTracker mVelocityTracker;
    private View mDownView;

    public ListItemSwipeListener(ListView listView)
    {
        this.mListView = listView;

        ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
        mSlop = vc.getScaledTouchSlop();
        mAnimationTime = listView.getContext().getResources().getInteger(android.R.integer.config_shortAnimTime);
    }

    @Override
    public boolean onTouch(View v, MotionEvent motionEvent) 
    {
        if (mViewWidth < 2) 
        {
            mViewWidth = mListView.getWidth();
        }

        switch(motionEvent.getActionMasked())
        {
            case MotionEvent.ACTION_DOWN:
            {
                if (mPaused)
                {
                    return false;
                }

                // Find the child view that was touched (perform a hit test)
                Rect rect = new Rect();
                int childCount = mListView.getChildCount();
                int[] listViewCoords = new int[2];
                mListView.getLocationOnScreen(listViewCoords);
                int x = (int) motionEvent.getRawX() - listViewCoords[0];
                int y = (int) motionEvent.getRawY() - listViewCoords[1];
                View child;
                for (int i = 0; i < childCount; i++) {
                    child = mListView.getChildAt(i);
                    child.getHitRect(rect);
                    if (rect.contains(x, y)) {
                        mDownView = child;                        
                        Log.d(TAG, "index: "+i);
                        break;
                    }
                }

                if (mDownView != null) {
                    mDownX = motionEvent.getRawX();                    

                    mVelocityTracker = VelocityTracker.obtain();
                    mVelocityTracker.addMovement(motionEvent);                    
                }

                return false;
            }
            case MotionEvent.ACTION_MOVE:
            {
                if (mVelocityTracker == null || mPaused)
                {
                    break;
                }
                mVelocityTracker.addMovement(motionEvent);
                float deltaX = motionEvent.getRawX() - mDownX;
                if (Math.abs(deltaX) > mSlop) 
                {
                    mSwiping = true;
                }

                if (mSwiping)
                {
                    mDownView.setTranslationX(deltaX);

                    return true;
                }
                break;                
            }
            case MotionEvent.ACTION_UP:
            {
                if (mVelocityTracker == null) 
                {
                    break;
                }                           

                float deltaX = motionEvent.getRawX() - mDownX;                  
                mVelocityTracker.recycle();
                mVelocityTracker = null;
                mDownX = 0;
                mDownView = null;                   
                mSwiping = false;
                break;
            }
            case MotionEvent.ACTION_CANCEL:
            {
                break;
            }
        }
        return false;
    }

    public AbsListView.OnScrollListener makeScrollListener() 
    {
        return new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i1, int i2) {
            }
        };
    }

    public void setEnabled(boolean enabled) 
    {
        mPaused = !enabled;
    }
}

1 个答案:

答案 0 :(得分:0)

一旦视图被翻译,Android中的getHitRect()就会出错,解决方案如下: Strange View.getHitRect() behaviour

相关问题