Android 使用Scroller自动滚动第一种实现

来源:互联网 发布:原生js获取子元素节点 编辑:程序博客网 时间:2024/05/02 03:07



源码下载 , 效果图如下:



1. 自定义视图继承自ViewGroup,覆写onMeasure,onLayout,之前文章介绍过覆写这两个方法。

2. 提供两个方法供两个button使用,向左向右移动。调用startScroll (int startX, int startY, int dx, int dy)方法, 以提供的起始点和将要滑动的距离开始滚动。滚动会使用缺省值250ms作为持续时间。

3. 设置滚动的便宜量childView.offsetLeftAndRight(leftAndRightOffset);

4. 调用invalidate()进行重绘

5. 延迟短暂时间,返回执行3,4步骤


public class CustomViewGroup extends ViewGroup {    // ===========================================================    // Constants    // ===========================================================        private static final int DELAY_MILLIS = 1000 / 60;        // ===========================================================    // Fields    // ===========================================================        // 记录上次滚动的位置,用于计算滚动偏移量    private int mOffsetX = 0;        private Scroller mScroller = new Scroller(getContext());        private Handler mHandler = new Handler();        private Runnable mScrollerRunnable = new ScrollerRunnable();        // 每次滚动的距离    private int mScrollWidth = 300;        // ===========================================================    // Constructors    // ===========================================================    public CustomViewGroup(Context context) {        super(context);    }    public CustomViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);    }        public CustomViewGroup(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }        // ===========================================================    // Getter & Setter    // ===========================================================    /**     * 向右滚动     */    public void scrollToRight() {        scroll(true);    }        /**     * 向左滚动     */    public void scrollToLeft() {        scroll(false);    }        // ===========================================================    // Methods for/from SuperClass/Interfaces    // ===========================================================    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);                measureChildren(widthMeasureSpec, heightMeasureSpec);                setMeasuredDimension(widthSize, heightSize);    }        @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        int childCount = getChildCount();        for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);                        int measuredWidth = childView.getMeasuredWidth();            int measuredHeight = childView.getMeasuredHeight();                        childView.layout(mOffsetX, 0, mOffsetX + measuredWidth, measuredHeight);        }    }        // ===========================================================    // Methods    // ===========================================================        private void scroll(boolean scrollToRight) {        // 向右滚动举例是正值,反之负值        int scrollWidth = scrollToRight ? mScrollWidth: -mScrollWidth;                // 此次滚动的X轴终点位置        int scrollFinalX = mOffsetX + scrollWidth;                // 不能移出边界        if (scrollFinalX > 300 || scrollFinalX < 0) {            return;        }        // 清除        mHandler.removeCallbacks(mScrollerRunnable);                // 触发开始滚动        mScroller.startScroll(mOffsetX, 0, scrollWidth, 0);                // 子线程中间隔段时间重绘视图        mHandler.post(mScrollerRunnable);    }        /**     * 设置view滚动后的x坐标的位置     *      * @param offsetX     */    private void setOffsetX(int offsetX) {        if (offsetX == mOffsetX) {            return;        }                final int leftAndRightOffset = offsetX - mOffsetX;                int childCount = getChildCount();        for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);            childView.offsetLeftAndRight(leftAndRightOffset);        }                mOffsetX = offsetX;    }                // ===========================================================    // Inner and Anonymous Classes    // ===========================================================    private class ScrollerRunnable implements Runnable {        @Override        public void run() {            final Scroller scroller = mScroller;                        if (scroller.computeScrollOffset()) {                                setOffsetX(scroller.getCurrX());                                // 位置发生偏移,重绘                invalidate();                                // 每过间隔时间,再次执行当前子线程                mHandler.postDelayed(this, DELAY_MILLIS);            }        }    }            }




扩展:

学习下Scroller原理



原文地址:http://blog.csdn.net/love_world_/article/details/8126234



原创粉丝点击