1

我有一个在框架布局内的视图。我正在跟踪视图的 ontouch 事件,我希望视图在我移动手指时以平滑的滚动方式上下垂直滚动。目前视图滚动但我无法正确计算(也许是逻辑),滚动非常不稳定。这类似于滑动抽屉,就我而言,滑动抽屉不起作用。

感谢您对这个问题的任何帮助。谢谢!

    cardImage.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            float startY = 0;
            float moveY = 0;
            float velocityX=0, velocityY=0;
            int index = event.getActionIndex();
            int action = event.getActionMasked();
            int pointerId = event.getPointerId(index);

            switch(event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    startY = event.getRawY();
                    isTouchUp = false;                      

                    if(mVelocityTracker == null) {
                        // Retrieve a new VelocityTracker object to watch the velocity of a motion.
                        mVelocityTracker = VelocityTracker.obtain();
                    }
                    else {
                        // Reset the velocity tracker back to its initial state.
                        mVelocityTracker.clear();
                    }
                    // Add a user's movement to the tracker.
                    mVelocityTracker.addMovement(event);

                    previousRawY = startY;

                    return true;
                case MotionEvent.ACTION_MOVE:
                    moveY = event.getRawY();
                    isTouchUp = false;

                    mVelocityTracker.addMovement(event);
                    // When you want to determine the velocity, call 
                    // computeCurrentVelocity(). Then call getXVelocity() 
                    // and getYVelocity() to retrieve the velocity for each pointer ID. 
                    mVelocityTracker.computeCurrentVelocity(1000);
                    // Log velocity of pixels per second
                    // Best practice to use VelocityTrackerCompat where possible.
                            velocityX = VelocityTrackerCompat.getXVelocity(mVelocityTracker, pointerId);
                            velocityY = VelocityTrackerCompat.getYVelocity(mVelocityTracker, pointerId);


                    if(Math.abs(velocityX) + 100 > Math.abs(velocityY)) {
                        // right left
                    }
                    else {
                        // up down                          
                        if(action != MotionEvent.ACTION_OUTSIDE) {                          
                            if(moveY > previousRawY) {
                                // Moving down


                                for(float i=0;i<moveY-previousRawY;i++) {
                                    cardCurrentOffset += (moveY-previousRawY)/(moveY-previousRawY);

                                    cardImage.setTranslationY(cardCurrentOffset);
                                }
                            }
                            else {
                                // Moving Up

                                if(cardImage.getY() > topHeaderLayout.getBottom()) {

                                    for(float i=0;i<previousRawY-moveY;i++) {
                                        cardCurrentOffset -= (previousRawY-moveY)/(previousRawY-moveY);

                                        cardImage.setTranslationY(cardCurrentOffset);
                                    }
                                }
                            }

                            previousRawY = moveY;
                        }
                    }

                    return true;    
                case MotionEvent.ACTION_UP:
                    isTouchUp = true;
                    return true;
                case MotionEvent.ACTION_CANCEL:
                    // Return a VelocityTracker object back to be re-used by others.
                    mVelocityTracker.recycle();
                    return true;
                case MotionEvent.ACTION_OUTSIDE:
                    return false;
                default:
                    return false;
            }
        }
    });    
4

2 回答 2

1

试试这个(你可以在顶部/底部添加一些检查或一扔):

class ScrollingTextView extends TextView {
    private GestureDetector mDetector;

    public ScrollingTextView(Context context) {
        super(context);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 30; i++) {
            sb.append("Line #").append(i).append("\n");
        }
        setTextSize(24);
        setText(sb);
        setTextColor(0xffeeeeee);
        mDetector = new GestureDetector(mListener);
    }

    private OnGestureListener mListener = new SimpleOnGestureListener() {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            scrollBy(0, (int) distanceY);
            return true;
        }
    };

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDetector.onTouchEvent(event);
        return true;
    }
}

为了测试它,在 Activity.onCreate 中添加以下内容:

View v = new ScrollingTextView(this);
setContentView(v);
于 2013-10-13T09:39:57.493 回答
0

我观察到诸如边距之类的动态变化的属性并不像我想要的那样平滑。而不是我使用TranslateAnimations; 诀窍是在滚动期间应用动画,并在修饰时更改实际边距。

于 2013-10-13T08:46:43.793 回答