1. 程式人生 > >自定義可拖拽的view

自定義可拖拽的view

簡介幾個方法

在我們要做這麼一個自定義view時得先把下面幾個方法搞清楚,不然你是弄不出來的,先前我只是看了網上簡單介紹沒有真正搞懂他們,就做的一直有些小問題。其實方法很簡單,但必須真正理解。

MotionEvent:
getRawX(); //你觸控的x座標,相對於螢幕的位置,這裡是相對整個螢幕的,與後面說的"可用"螢幕有區別。
getX(); //你第一個手指觸控的x座標,相對於你觸控的控制元件本身而言的。如果你兩個手指下去,想獲取第二的觸控位置就呼叫get(1),後面依次類推,這個先了解一下,我弄那個兩個手勢控制縮小放大才用到。
View:
getTop();//獲取此view相對於父view的位置,如果"沒有父view"就是相對於"可用"螢幕而言,這裡是關鍵,其餘三個位置雷同。
setFrame();//裡面有四個引數,說法類似getTop(),後面程式碼裡有再次提到。

可拖拽的View程式碼

直接上程式碼自己看,需要註解的都寫明瞭,邏輯也比較簡單清晰。

package com.xiong.tucao;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import
android.view.WindowManager; import android.widget.ImageView; public class DragTextView extends ImageView{ //相對於父控制元件的觸控位置,用於處理拖拽 private float xDown,yDown,xUp,yUp; private int extra; public DragTextView(Context context) { this(context, null, 0); } public DragTextView(Context context, AttributeSet attrs) { this
(context, attrs, 0); } public DragTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); dm = new DisplayMetrics();//獲取螢幕寬高,處理越界的時候用到 Activity activity = (Activity) context; activity.getWindowManager().getDefaultDisplay().getMetrics(dm); } //重寫觸控的方法 @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK){ case MotionEvent.ACTION_DOWN: onTouchDown(event); break; case MotionEvent.ACTION_MOVE: onTouchMove(event); break; case MotionEvent.ACTION_UP: isOver(); break; } return true; } /** 按下 **/ private void onTouchDown(MotionEvent event){ xDown = event.getX(); yDown = event.getY(); xUp = event.getRawX(); yUp = event.getRawY(); extra = (int) (yUp - yDown - getTop()); } /** 拖拽 **/ private void onTouchMove(MotionEvent event) { int left, right, top, bottom; top = (int) (yUp - yDown) - extra; bottom = top + getHeight(); left = (int) (xUp - xDown); right = left + getWidth(); //Top position, relative to parent這是該方法其中top引數的官方解釋,反正我是被誤導了,我不知道這個父親到底是怎樣定義的 // 我目前的理解是它的所有引數位置是相對於該view放置的那個xml佈局的位置,那個xml佈局最外面的那個layout才是父view。 //為什麼要說的這麼繞,就是它的位置不是相對螢幕的,因為你的應用可能有tab佔了位置,那塊位置就不能算。如果理解了這些話就能知道為什麼會有extra了。 this.setFrame(left, top, right, bottom); xUp = event.getRawX(); yUp = event.getRawY(); } /** * 拖拽時判斷是否越界 */ private void isOver() { int width = this.getWidth()/3; int height = this.getHeight()/3; int left = getLeft(),right=getRight(),top=getTop(),bottom=getBottom(); //針對整個可用螢幕的越界,必須還能看到控制元件的1/3 if (this.getBottom() < height){ bottom = height; top = bottom - getHeight(); } if (this.getRight() < width){ right = width; left = right - getWidth(); } if (this.getTop() > dm.heightPixels - extra - height){ top = dm.heightPixels - extra - height; bottom = top + getHeight(); } if (this.getLeft() > dm.widthPixels - width){ left = dm.widthPixels - width; right = left + getWidth(); } if (this.getBottom() < height || this.getLeft() < - width || this.getRight() > dm.widthPixels - width || this.getTop() > dm.heightPixels - extra - height) { setFrame(left, top, right, bottom); } } }

是不是很簡單呢,最後就是使用它了,你以前的ImageView怎麼用的那它就怎麼用。若對某些話不理解,自己列印下它們的值就一清二楚了。