您的位置:首页 > 移动开发 > Android开发

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

2012-10-29 22:21 627 查看
源码下载 , 效果图如下:



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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐