Android -- View移動的六種方法


layout()

如果你將滑動后的目標位置的坐標傳遞給layout(),這樣子就會把view的位置給重新布置了一下,在視覺上就是view的一個滑動的效果。

public class DragView extends View{
    private int lastX;
    private int lastY;

    public DragView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
  
    public boolean onTouchEvent(MotionEvent event) {
        
        //獲取到手指處的橫坐標和縱坐標
        int x = (int) event.getX();
        int y = (int) event.getY();
        
        switch(event.getAction()){
        	case MotionEvent.ACTION_DOWN:
            	lastX = x;
           		lastY = y;
            break;
        	case MotionEvent.ACTION_MOVE:
            	//計算移動的距離
            	int offX = x - lastX;
            	int offY = y - lastY;
            	//調用layout方法來重新放置它的位置
           		layout(getLeft()+offX, getTop()+offY,
                    getRight()+offX    , getBottom()+offY);
            break;
        }
        return true;
    }
}

offsetLeftAndRight() offsetTopAndBottom()

其實這兩個方法分別是對左右移動和上下移動的封裝,傳入的就是偏移量

public boolean onTouchEvent(MotionEvent event) {
        //獲取到手指處的橫坐標和縱坐標
        int x = (int) event.getX();
        int y = (int) event.getY();
        
        switch(event.getAction()){
        	case MotionEvent.ACTION_DOWN:
          	   lastX = x;
         	   lastY = y;
            break;
        	case MotionEvent.ACTION_MOVE:
	            //計算移動的距離
        	    int offX = x - lastX;
        	    int offY = y - lastY;
        	    offsetLeftAndRight(offX);
              	offsetTopAndBottom(offY);
            break;
        }
        return true;
    }

LayoutParams

public boolean onTouchEvent(MotionEvent event) {
        //獲取到手指處的橫坐標和縱坐標
        int x = (int) event.getX();
        int y = (int) event.getY();
        
        switch(event.getAction()){
 	       case MotionEvent.ACTION_DOWN:
	            lastX = x;
    	        lastY = y;
            break;
       		case MotionEvent.ACTION_MOVE:
           		//計算移動的距離
	            int offX = x - lastX;
	            int offY = y - lastY;
	            ViewGroup.MarginLayoutParams mlp = 
    	                (MarginLayoutParams) getLayoutParams();
        	    mlp.leftMargin = getLeft()+offX;
            	mlp.topMargin = getTop()+offY;
	            setLayoutParams(mlp);
            break;
        }
        return true;
    }

scrollTo() scrollBy()

sceollTo(x,y)傳入的應該是移動的終點坐標

scrollBy(dx,dy)傳入的是移動的增量。

通過scrollBy傳入的值應該是你需要的那個增量的相反數!

public boolean onTouchEvent(MotionEvent event) {
        //獲取到手指處的橫坐標和縱坐標
        int x = (int) event.getX();
        int y = (int) event.getY();
        
        switch(event.getAction()){
      		case MotionEvent.ACTION_DOWN:
	            lastX = x;
    	        lastY = y;
            break;
	        case MotionEvent.ACTION_MOVE:
	            //計算移動的距離
    	        int offX = x - lastX;
        	    int offY = y - lastY;
		        ((View) getParent()).scrollBy(-offX,- offY);
            break;
        }
        return true;
    }

Scroller

步驟一:

​ 初始化Scroller對象,即mScroller = new Scroller(context)

步驟二:

​ 重寫computeScroll()方法,實現模擬滑動。可以復制下面的末模板代碼:

public void computeScroll() {
	super.computeScroll();
	if(mScroller.computeScrollOffset()){
		((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
	}
	invalidate();//必須要調用
}

步驟三:

開啟模擬過程,在合適的地方(一般都在move中)startScroll方法。它有兩個重載方法如下:

startScroll(int startX,int startY, int dx,int dy,int duration)

startScroll(int startX,int startY,int dx,int dy)

需要說明的是:

  1. computeScrollOffset方法用來判斷是否完成了整個滑動,返回為true,則說明沒有完成,否則則完成滑動。
  2. getCurrY()以及getCurrX()獲得的是當前的滑動坐標。
  3. 最后必須要用invalidate方法來刷新。因為computeScroll方法不會自動調用,是在draw方法中被調用的。所以必須使用invalidate刷新,就會調用draw方法,自然就會調用computeScroll方法了。這樣子就會實現循環調用。
  4. 在startScroll中,偏移量跟使用scrollBy方法中的偏移量用法是一樣的,即也必須填寫你實際想要移動距離的相反數。也就是你實際想讓它偏移一個正值,這里就填寫它相應的負值,如果想偏移一個負值,這里就填寫相應的正值!
public class DragView extends View{
    
    private int lastX;
    private int lastY;
    private Scroller mScroller;

    public DragView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }
  
    public boolean onTouchEvent(MotionEvent event) {
        //獲取到手指處的橫坐標和縱坐標
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch(event.getAction()){
        	case MotionEvent.ACTION_DOWN:
         	   lastX = x;
         	   lastY = y;
            break;
       		case MotionEvent.ACTION_MOVE:
            	//計算移動的距離
	            int offX = x - lastX;
	            int offY = y - lastY;
	            View viewGroup = (View) getParent();
	            ((View) getParent()).scrollBy(-offX,- offY);
            break;
        case MotionEvent.ACTION_UP:
			View viewGroup = (View) getParent();
            //開啟滑動,讓其回到原點
            mScroller.startScroll(viewGroup.getScrollX(),
                    viewGroup.getScrollY(),
                    -viewGroup.getScrollX() ,-viewGroup.getScrollY());
            break;
        }
        return true;
    }
  	public void computeScroll() {
		super.computeScroll();
		if(mScroller.computeScrollOffset()) {
			((View)getParent()).scrollTo(mScroller.getCurrX(),
                        mScroller.getCurrY());
		}  
		invalidate();//必須要調用
	}
}

詳細:《Android -- Scrollerhttp://www.cnblogs.com/yydcdut/p/4472340.html

ViewDragHelper

ViewDragHelper可以看這篇文章:《Android -- ViewDragHelperhttp://www.cnblogs.com/yydcdut/p/4945052.html

我是天王蓋地虎的分割線

參考:http://www.cnblogs.com/fuly550871915/p/4985053.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM