当前位置: 代码迷 >> Android >> Android Scroller容易用法
  详细解决方案

Android Scroller容易用法

热度:33   发布时间:2016-04-28 03:11:37.0
Android Scroller简单用法

1.知识点

  • 在了解Scorller类之前应先知道View的ScrollTo(int x, int y)/ScrollBy(int x, int y)之间的区别,了解什么是视图坐标,什么是布局坐标。之后我们来看一下Scroller的源码。

Scoller一般用在自定义View中

public class Scroller  {        private int mStartX;    //起始坐标点 ,  X轴方向      private int mStartY;    //起始坐标点 ,  Y轴方向      private int mCurrX;     //当前坐标点  X轴, 即调用startScroll函数后,经过一定时间所达到的值      private int mCurrY;     //当前坐标点  Y轴, 即调用startScroll函数后,经过一定时间所达到的值           private float mDeltaX;  //应该继续滑动的距离, X轴方向      private float mDeltaY;  //应该继续滑动的距离, Y轴方向      private boolean mFinished;  //是否已经完成本次滑动操作, 如果完成则为 true        //构造函数      public Scroller(Context context) {          this(context, null);      }      public final boolean isFinished() {          return mFinished;      }      //强制结束本次滑屏操作      public final void forceFinished(boolean finished) {          mFinished = finished;      }      public final int getCurrX() {          return mCurrX;      }       /* Call this when you want to know the new location.  If it returns true,      * the animation is not yet finished.  loc will be altered to provide the      * new location. */        //根据当前已经消逝的时间计算当前的坐标点,保存在mCurrX和mCurrY值中      public boolean computeScrollOffset() {          if (mFinished) {  //已经完成了本次动画控制,直接返回为false              return false;          }          int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);          if (timePassed < mDuration) {              switch (mMode) {              case SCROLL_MODE:                  float x = (float)timePassed * mDurationReciprocal;                  ...                  mCurrX = mStartX + Math.round(x * mDeltaX);                  mCurrY = mStartY + Math.round(x * mDeltaY);                  break;              ...          }          else {              mCurrX = mFinalX;              mCurrY = mFinalY;              mFinished = true;          }          return true;      }      //开始一个动画控制,由(startX , startY)在duration时间内前进(dx,dy)个单位,即到达坐标为(startX+dx , startY+dy)出      public void startScroll(int startX, int startY, int dx, int dy, int duration) {          mFinished = false;          mDuration = duration;          mStartTime = AnimationUtils.currentAnimationTimeMillis();          mStartX = startX;       mStartY = startY;          mFinalX = startX + dx;  mFinalY = startY + dy;          mDeltaX = dx;            mDeltaY = dy;          ...      }  }  

一些方法介绍

mScroller.getCurrX() //获取mScroller当前水平滚动的位置  mScroller.getCurrY() //获取mScroller当前竖直滚动的位置  mScroller.getFinalX() //获取mScroller最终停止的水平位置  mScroller.getFinalY() //获取mScroller最终停止的竖直位置  mScroller.setFinalX(int newX) //设置mScroller最终停留的水平位置,没有动画效果,直接跳到目标位置  mScroller.setFinalY(int newY) //设置mScroller最终停留的竖直位置,没有动画效果,直接跳到目标位置    //滚动,startX, startY为开始滚动的位置,dx,dy为滚动的偏移量, duration为完成滚动的时间  mScroller.startScroll(int startX, int startY, int dx, int dy) //使用默认完成时间250ms  mScroller.startScroll(int startX, int startY, int dx, int dy, int duration)    mScroller.computeScrollOffset() //返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。这是一个很重要的方法,通常放在View.computeScroll()中,用来判断是否滚动是否结束。
  • View的computeScroll()方法使用,此方法在绘制View的每一个子view时都被调用

2.举例


实现下拉刷新的效果
        
 主要代码:
public class CustomView extends RelativeLayout {	private static final String TAG = "CustomView";	private Scroller mScroller;	private GestureDetector mGestureDetector;	public boolean flag = true;	public StateListener stateListener;	public CustomView(Context context) {		this(context, null);	}		public CustomView(Context context, AttributeSet attrs) {		super(context, attrs);		setClickable(true);		setLongClickable(true);		mScroller = new Scroller(context);		mGestureDetector = new GestureDetector(context, new CustomGestureListener());	}	public interface StateListener	{		public void changeText();		public void recoverText();	}	public void setStateListener(StateListener statelistener)	{		this.stateListener = statelistener;	}	//调用此方法滚动到目标位置	public void smoothScrollTo(int fx, int fy) {		int dx = fx - mScroller.getFinalX();		int dy = fy - mScroller.getFinalY();		smoothScrollBy(dx, dy);	}	//调用此方法设置滚动的相对偏移	public void smoothScrollBy(int dx, int dy) {		//设置mScroller的滚动偏移量		mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);		invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果	}		//在绘制View时,会在draw()过程调用该方法。	@Override	public void computeScroll() {			//先判断mScroller滚动是否完成		if (mScroller.computeScrollOffset()) {					//这里调用View的scrollTo()完成实际的滚动			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());						//必须调用该方法,否则不一定能看到滚动效果			postInvalidate();		}		super.computeScroll();	}		@Override	public boolean onTouchEvent(MotionEvent event) {		switch (event.getAction()) {		case MotionEvent.ACTION_UP :			Log.i(TAG, "get Sy" + getScrollY());			System.out.println(getScrollX()+"x--"+getScrollY()+"y");			smoothScrollTo(0, 0);			System.out.println("up");			break;		default:			int distance = getScrollY();			System.out.println("distance"+distance);			if(distance <= 0)			{				flag = true;				if(distance > -200)				{					stateListener.recoverText();				}				else if(distance < -200)				{					stateListener.changeText();				}				return mGestureDetector.onTouchEvent(event);			}else			{				flag = false;				return false;			}		}		return super.onTouchEvent(event);	}		class CustomGestureListener implements GestureDetector.OnGestureListener {		@Override		public boolean onDown(MotionEvent e) {			// TODO Auto-generated method stub			return true;		}		@Override		public void onShowPress(MotionEvent e) {			// TODO Auto-generated method stub					}		@Override		public boolean onSingleTapUp(MotionEvent e) {			// TODO Auto-generated method stub			return false;		}		@Override		public boolean onScroll(MotionEvent e1, MotionEvent e2,				float distanceX, float distanceY) {			if(flag)			{int dis = (int)((distanceY-0.5)/4);			Log.i(TAG, dis + ".");			smoothScrollBy(0, dis);}			return false;		}		@Override		public void onLongPress(MotionEvent e) {			// TODO Auto-generated method stub					}		@Override		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,				float velocityY) {			// TODO Auto-generated method stub			e1.getY();			e2.getY();			System.out.println(e1.getY()+"------"+e2.getY());			return false;		}			}}




  相关解决方案