Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Scroller簡單用法

Android Scroller簡單用法

編輯:關於Android編程

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;
		}
		
	}
}




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved