Android 中的平滑滚动 [英] Smooth scrolling in Android

查看:18
本文介绍了Android 中的平滑滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

市场上有一个应用程序叫做浮动图像.此应用程序具有最流畅的滚动逻辑之一.基本上,该应用程序有一个覆盖整个屏幕的空白画布,然后在空白画布顶部显示了一些图像.用户可以滑动,应用程序沿滑动方向移动图像.此外,它也可以进行动态滚动.此外,没有滚动条,因此开发人员似乎创建了一个实现所有平滑滚动逻辑的自定义视图.

There is an app in the market place called Floating images. This app has one of the smoothest scrolling logic. Basically the app has a blank canvas covering whole screen and then there are some images displayed on top of the blank canvas. User can swipe and the app moves the image in the direction of swipe. Plus it does kinetic scrolling too. Plus there are no scrollbars so it seems like the developer has created a custom view implementing all smooth scrolling logic.

如果我能得到它的来源就太棒了..但是任何人都有任何关于如何实现这种功能的伪代码或逻辑.任何线索、网站链接都会有所帮助.

it would be awesome if i could get the source of it.. but anyone has any pseudo code or logic on how to implement this kind of feature. Any leads , site links would be helpful.

推荐答案

我没有使用 OpenGL 和加速计的经验,但是滑动(在 Android 的 API 中称为 fling)并不难实现.制作此类自定义 View 时,您需要做的第一件事是实现 GestureDetector 并在视图的 onTouchEvent() 中调用其 onTouchEvent())

I have no experience with OpenGL nor accelerometer, but swipe (called fling in Android's API) is not hard to achieve. First thing you need when making such a custom View, is implementing a GestureDetector and call its onTouchEvent() in your view's onTouchEvent()

GestureDetector mGD = new GestureDetector(getContext(),
                                        new SimpleOnGestureListener() {

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
        // beware, it can scroll to infinity
        scrollBy((int)distanceX, (int)distanceY);
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY) {
        mScroller.fling(getScrollX(), getScrollY(),
                -(int)vX, -(int)vY, 0, (int)mMaxScrollX, 0, (int)mMaxScrollY);
        invalidate(); // don't remember if it's needed
        return true;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        if(!mScroller.isFinished() ) { // is flinging
            mScroller.forceFinished(true); // to stop flinging on touch
        }
        return true; // else won't work
    }
});

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

虽然 OnGestureListener.onScroll() 直接调用 View.scrollBy(),但对于 onFling() 方法,您需要一个 <代码>滚动条.

While OnGestureListener.onScroll() calls directly View.scrollBy(), for the onFling() method you'll need a Scroller.

Scroller 是一个简单的对象,正如参考文献所说,它封装了滚动.它可用于连续滚动或对甩动做出反应.Scroller.fling() 在其内部开始模拟"fling 滚动,通过观看它,您可以通过连续重绘动画复制其平滑度:

Scroller is a simple object that, as reference says, encapsulates scrolling. It can be used for continuous scrolling or to react to flings. Scroller.fling() begin a "simulation" of fling scroll inside itself, and by watching it you can copy its smoothness with a continuous redrawing animation:

@Override
protected void onDraw(Canvas canvas) {
    // ....your drawings....

    // scrollTo invalidates, so until animation won't finish it will be called
    // (used after a Scroller.fling() )
    if(mScroller.computeScrollOffset()) {
        scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    }
}

也就是说,在动画运行之前,计算我们到达的点并滚动到那里.

that is, until animation is running, calculate the point we reached and scroll there.

最后一点:记得在你的 OnGestureListener.onDown() 中返回 true,即使你不想在 down 上做任何事情,否则它赢了不行.

As a last note: remember to return true in your OnGestureListener.onDown(), even if you don't want to do anything on down, or it won't work.

并且要小心,因为 Android 2.2 中的 Scroller 有一个错误,即使它达到您作为参数传递的限制(但计算的偏移量尊重它们,所以它实际上不会移动).

And be careful, because Scroller in Android 2.2 has a bug for which the fling animation will not actually end even if it reaches the limits you passed as arguments (yet computed offset respects them, so it won't actually move).

这篇关于Android 中的平滑滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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