从下到上滚动ListView

时间:2014-05-19 19:55:58

标签: android listview animation android-scrollview

有一个ListView,当活动开始时,我希望它从底部滚动到顶部。我可以通过在myListView.setStackFromBottom(true)中设置onCreate来实现此功能,以便在活动加载时列表位于底部。

然后我覆盖onWindowFocusChanged并使用smoothScrollToPosition(0)将列表滚动到顶部。但是,我需要滚动速度逐渐减慢,因为它到达顶部,类似于fling的样子。有没有办法用动画或其他方式做到这一点?

感谢。

1 个答案:

答案 0 :(得分:2)

您可以使用CountDownTimer编写自己的卷轴。

import android.content.Context;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.Interpolator;
import android.widget.ScrollView;

public class SmoothScrollView extends ScrollView {

    private static final long SCROLL_DURATION = 1500; //milliseconds
    //interpolator for scroller
    private static final Interpolator INTERPOLATOR = new AnticipateOvershootInterpolator(1);

    private SmoothScroller smoothScroller;


    public SmoothScrollView(Context context) {
        this(context, null, 0);
    }


    public SmoothScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public SmoothScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setSmoothScrollingEnabled(true);
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (smoothScroller != null)//we are scrolling
            return true;
        else return super.onTouchEvent(ev);
    }

    @Override
    public boolean executeKeyEvent(KeyEvent ev) {
        if (smoothScroller != null)//we are scrolling
            return true;
        else return super.executeKeyEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (smoothScroller != null)//we are scrolling
            return true;
        else return super.onInterceptTouchEvent(ev);
    }

    public void smoothScrollTo(int scrollX, int scrollY) {
        if (smoothScroller != null) {
            smoothScroller.cancel();
        }
        int deltaY = scrollY - getScrollY();
    int deltaX = scrollX - getScrollX();
        smoothScroller = new SmoothScroller(SCROLL_DURATION, getScrollX(), getScrollY(), deltaX, deltaY);
        smoothScroller.start();
    }

    private class SmoothScroller extends CountDownTimer {

        private int fromX;
        private int fromY;
        private int deltaX;
        private int deltaY;
        private float scrollTime;

        public SmoothScroller(long scrollTime, int fromX, int fromY, int deltaX, int deltaY) {
            super(scrollTime, 1);
            this.scrollTime = scrollTime;
            this.fromX = fromX;
            this.fromY = fromY;
            this.deltaX = deltaX;
            this.deltaY = deltaY;
        }

        @Override
        public void onTick(long millisUntilFinished) {
                float delta = (scrollTime - millisUntilFinished) / scrollTime;
                delta = INTERPOLATOR.getInterpolation(delta);
                int x = fromX + ((int) (delta * deltaX));
                int y = fromY + ((int) (delta * deltaY));
                smoothScrollTo(x, y);
        }

        @Override
        public void onFinish() {
                float delta = 1f;
                int x = fromX + ((int) (delta * deltaX));
                int y = fromY + ((int) (delta * deltaY));
                smoothScroller = null;
                scrollTo(x, y);
        }
    }
}

这就是我使用的。只需根据您的需要更改INTERPOLATORSCROLL_DURATION,然后致电smoothScrollTo而不是scrollTo

我非常确定将ScrollView更改为ListView不会导致任何问题。