一:
原理就是響應控件的Touch事件予跌,在Touch事件中對移動進行處理籽暇,如果沒效果那你試著在布局文件中設置控件的 android:clickable="true"耘婚。
當然扯罐,大部分人都是直接想要解決方案,這里直接貼代碼肥照,后面會有一些說明脚仔。
-
1.首先在 你的 Activity 實現(xiàn) OnTouchListener 接口 ,并重寫onTouch 方法
implements OnTouchListener
-
2.activity中定義幾個變量先
private int screenWidth, screenHeight;
private int lastX, lastY,moveDownX;
private ImageView mTestIV; -
3.在Activity 的 onCreate方法中
mTestIV=(ImageView) findViewById(R.id.iv_test); mTestIV.setOnTouchListener(this); Display dis = this.getWindowManager().getDefaultDisplay(); screenWidth = dis.getWidth(); screenHeight = dis.getHeight();
-
4.重寫onTouch內(nèi)部方法
@Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); moveDownX= (int) event.getRawX(); } if (event.getAction() == MotionEvent.ACTION_MOVE){ int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; int top = v.getTop() + dy; int left = v.getLeft() + dx; if (top <= 0) { top = 0; } if (top >= screenHeight - mTestIV.getHeight()) { top = screenHeight - mTestIV.getHeight(); } if (left >= screenWidth - mTestIV.getWidth()) { left = screenWidth - mTestIV.getWidth(); } if (left <= 0) { left = 0; } v.layout(left, top, left + mTestIV.getWidth(), top + mTestIV.getHeight()); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); } if (event.getAction() == MotionEvent.ACTION_UP) { int tempDX = (int) event.getRawX() - moveDownX; if (Math.abs(tempDX) < 6) { // do your things return false;// 距離較小舆绎,當作click事件來處理 } } return true;// 返回true鲤脏,不執(zhí)行click事件 }
以上為全部代碼。
二:
現(xiàn)在我們來分析下實現(xiàn)步驟:
一:我們開始要實現(xiàn)控件拖動效果
原理比較簡單:
- 1.在按下的時候(MotionEvent.ACTION_DOWN)吕朵,開始記錄當前按下位置的坐標值猎醇;
- 2.然后在手指移動控件的時候(MotionEvent.ACTION_MOVE),不斷計算當前的位置的坐標并重繪控件的位置
這里說明下 一些知識點:
視圖的left 努溃, top 硫嘶, right , bottom 的值是針對其父視圖的相對位置梧税,left相當于X軸值沦疾, top相當于Y軸值(原點為該widget 的父控件的左上角的點)
getX是獲取以widget左上角為坐標原點計算的X軸坐標值
getRawX 獲取的是以屏幕左上角為坐標原點計算的X軸坐標值
做完以上步驟,可以實現(xiàn)正常的拖動第队,但這時候會發(fā)現(xiàn)哮塞,你拖動抬起手指后會執(zhí)行onClick事件。
現(xiàn)在分析下這件事出現(xiàn)的原因:
在Android中凳谦,對一個View同時調(diào)用OnTouch事件和OnClick事件時忆畅,導致事件沖突。
比如onClick事件打算執(zhí)行A動作尸执,OnTouch事件打算執(zhí)行B動作邻眷,但是在實際使用時會發(fā)現(xiàn)眠屎,當調(diào)用OnTouch時,有可能會同時執(zhí)行A肆饶,B兩個動作改衩,這是因為OnClick事件本身就是在OnTouch事件中發(fā)生的;
在onTouch事件中驯镊,如果返回true葫督,就不會執(zhí)行onClick,返回false板惑,就同時執(zhí)行onClick方法橄镜,要想把OnTouch和onClick事件完全的區(qū)分》氤耍可能過下列方法洽胶,解決該沖突問題:
就是在 OnTouch中的MotionEvent.ACTION_DOWN 時,記錄下點(X1裆馒,Y1)姊氓,在 MotionEvent.ACTION_UP 時,記錄下點(X2喷好,Y2)翔横,然后比對 倆點之間的距離,如果小于一個較小數(shù)值(比如6)梗搅,就認為是Click事件禾唁,onTouch中返回false,如果距離較大无切,可以當作onTouch事件去處理荡短,返回true: