触摸的Andr​​oid光滑垂直滚动 [英] Android smooth vertical scroll on touch

查看:90
本文介绍了触摸的Andr​​oid光滑垂直滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个观点,这是一个框架布局中。我跟踪视图的ontouch事件,我想的观点为我动我的手指在垂直平滑滚动的方式向上和向下滚动。目前认为春联,但我不能得到正确的计算(也许逻辑),滚动非常不稳定。这类似于抽屉的滑动和我的目的滑动抽屉是行不通的。

应该AP preciate这个问题的任何帮助。谢谢!

  cardImage.setOnTouchListener(新OnTouchListener(){        @覆盖
        公共布尔onTouch(视图V,MotionEvent事件){            浮startY = 0;
            浮moveY = 0;
            浮velocityX = 0,velocityY = 0;
            INT指数= event.getActionIndex();
            INT行动= event.getActionMasked();
            INT pointerId = event.getPointerId(指数);            开关(event.getAction())
            {
                案例MotionEvent.ACTION_DOWN:
                    startY = event.getRawY();
                    isTouchUp = FALSE;                    如果(mVelocityTracker == NULL){
                        //获得一个新的VelocityTracker对象观看运动的速度。
                        mVelocityTracker = VelocityTracker.obtain();
                    }
                    其他{
                        //重置速度跟踪回到初始状态。
                        mVelocityTracker.clear();
                    }
                    //用户的运动添加到跟踪。
                    mVelocityTracker.addMovement(事件);                    previousRawY = startY;                    返回true;
                案例MotionEvent.ACTION_MOVE:
                    moveY = event.getRawY();
                    isTouchUp = FALSE;                    mVelocityTracker.addMovement(事件);
                    //当你要确定速度,通话
                    // computeCurrentVelocity()。然后调用getXVelocity()
                    //和getYVelocity()来检索每个指针标识的速度。
                    mVelocityTracker.computeCurrentVelocity(1000);
                    //日志每秒的像素速度
                    //最佳实践,以尽可能使用VelocityTrackerCompat。
                            velocityX = VelocityTrackerCompat.getXVelocity(mVelocityTracker,pointerId);
                            velocityY = VelocityTrackerCompat.getYVelocity(mVelocityTracker,pointerId);
                    如果(Math.abs(velocityX)+ 100〕Math.abs(velocityY)){
                        // 右左
                    }
                    其他{
                        //上下
                        如果(行动!= MotionEvent.ACTION_OUTSIDE){
                            如果(moveY> previousRawY){
                                //向下移动
                                对于(浮点I = 0; I< moveY- previousRawY;我++){
                                    cardCurrentOffset + =(moveY- previousRawY)/(moveY- previousRawY);                                    cardImage.setTranslationY(cardCurrentOffset);
                                }
                            }
                            其他{
                                // 向上                                如果(cardImage.getY()> topHeaderLayout.getBottom()){                                    对于(浮点I = 0; I< previousRawY-moveY;我++){
                                        cardCurrentOffset - =(previousRawY-moveY)/(previousRawY-moveY);                                        cardImage.setTranslationY(cardCurrentOffset);
                                    }
                                }
                            }                            previousRawY = moveY;
                        }
                    }                    返回true;
                案例MotionEvent.ACTION_UP:
                    isTouchUp = TRUE;
                    返回true;
                案例MotionEvent.ACTION_CANCEL:
                    //返回回被重新使用由他人VelocityTracker对象。
                    mVelocityTracker.recycle();
                    返回true;
                案例MotionEvent.ACTION_OUTSIDE:
                    返回false;
                默认:
                    返回false;
            }
        }
    });


解决方案

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

 类ScrollingTextView扩展的TextView {
    私人GestureDetector mDetector;    公共ScrollingTextView(上下文的背景下){
        超级(上下文);
        StringBuilder的SB =新的StringBuilder();
        对(INT I = 0; I&小于30;我++){
            sb.append(行#)追加(我).append(\\ n);
        }
        setTextSize(24);
        的setText(某人);
        setTextColor(0xffeeeeee);
        mDetector =新GestureDetector(mListener);
    }    私人OnGestureListener mListener =新SimpleOnGestureListener(){
        @覆盖
        公共布尔onScroll(MotionEvent E1,E2 MotionEvent,浮distanceX,浮distanceY){
            scrollBy(0,(int)的distanceY);
            返回true;
        }
    };    @覆盖
    公共布尔onTouchEvent(MotionEvent事件){
        mDetector.onTouchEvent(事件);
        返回true;
    }
}

要测试它添加以下的Activity.onCreate:

 视图V =新ScrollingTextView(本);
的setContentView(五);

I have a view that's inside a frame layout. I am tracking the ontouch event for the view and I want the view to scroll vertically in a smooth scrolling fashion up and down as I move my finger. At the moment the view scrolls but I can't get the calculation right (and perhaps logic), the scrolling is very choppy. This is similar to Sliding Drawer and for my purpose Sliding Drawer is not going to work.

Would appreciate any help with this problem. Thank you!

    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;
            }
        }
    });    

解决方案

try this one (you can add some checks at the top/bottom or fling as well):

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;
    }
}

to test it add the following in Activity.onCreate:

View v = new ScrollingTextView(this);
setContentView(v);

这篇关于触摸的Andr​​oid光滑垂直滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆