View滑動-跟隨手指移動
阿新 • • 發佈:2019-02-20
對View的移動,實現的方法有好幾種,原理是通過改變View的位置來移動View,下面來實現這樣的效果
- 動畫的方法
通過改變View的tranlationX和tranlationY的值來實現移動,首先來寫一個自定義View類,重寫onTouchEvent方法,實現構造方法
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super (context, attrs);
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;//這裡我們要消費這個事件,所以返回了true
}
}
關於移動的處理邏輯都在onTouchEvent方法中,下面的程式碼主要針對onTouchEvent方法修改,其它程式碼不再貼上了
首先要獲取手指點選移動在螢幕上的座標,使用
int x = (int )event.getRawX();//獲取x軸上的位置
int y = (int)event.getRawY();//獲取y軸上的位置
處理事件的模板程式碼
switch(event.getAction()){
case MotionEvent.ACTION_DOWN://點選事件
break;
case MotionEvent.ACTION_MOVE://移動事件
break;
case MotionEvent.ACTION_UP://離開事件
break;
default:
break;
}
通過判斷事件的型別,將在ACTION_MOVE事件中計算移動前後的差值來設定View的translationX和translationY值來改變View的位置,這裡需要記錄上次的位置,所以需要2個變數,程式碼如下
private int mLaxtX;
private int mLaxtY;
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int deltaX = x - mLastX;//計算x座標上的差值
int deltaY = y - mLastY;//計算y座標上的差值
float tranX = getTranslationX() + deltaX ;//要平移的x值
float tranY = getTranslationY() + deltaY;//要平移的y值
setTranslationX(tranX);//設定值
setTranslationY(tranY);
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
mLastX = x;//記錄上次的座標
mLastY = y;
return true;
}
- layout方法
View在繪製的時候,會呼叫onLayout方法來設定顯示的位置,可以通過這個方法來實現移動
//layout方法實現
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//計算偏移量
int offsetX = x - mLastX;
int offsetY = y - mLastY;
//重新佈局
layout(getLeft() + offsetX, getTop() + offsetY,
getRight() + offsetX, getBottom() + offsetY);
//也可以使用下面這種方法
// offsetLeftAndRight(offsetX);
// offsetTopAndBottom(offsetY);
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
mLastX = x;
mLastY = y;
- LayoutParams
LayoutParams儲存了一個View的佈局引數,通過改變這個引數,重繪View也可以實現移動
//LayoutParams方法
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - mLastX;
int offsetY = y - mLastY;
//示例程式碼的父View是LinearLayout
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetX;
layoutParams.topMargin = getTop() + offsetY;
//下面這兩句都可以使用,setLayoutParams也會呼叫requestLayout
// setLayoutParams(layoutParams);
requestLayout();
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
這裡先介紹這幾種方法~~~
完整程式碼如下:
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private int mLastX;
private int mLastY;
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
//動畫實現移動程式碼
//--------------------------------------------------
// switch (event.getAction()) {
// case MotionEvent.ACTION_DOWN:
//
// break;
// case MotionEvent.ACTION_MOVE:
// int delaltax = x - mLastX;
// int delaltaY = y - mLastY;
// float tranX = getTranslationX() + delaltax;
// float tranY = getTranslationY() + delaltaY;
// setTranslationX(tranX);
// setTranslationY(tranY);
// break;
// case MotionEvent.ACTION_UP:
//
// break;
// default:
// break;
// }
//-----------------------------------------------
//layout方法實現
// switch (event.getAction()) {
// case MotionEvent.ACTION_DOWN:
// break;
// case MotionEvent.ACTION_MOVE:
// //計算偏移量
// int offsetX = x - mLastX;
// int offsetY = y - mLastY;
// //重新佈局
// layout(getLeft() + offsetX, getTop() + offsetY,
// getRight() + offsetX, getBottom() + offsetY);
// //也可以使用下面這種方法
//// offsetLeftAndRight(offsetX);
//// offsetTopAndBottom(offsetY);
// break;
// case MotionEvent.ACTION_UP:
// break;
// default:
// break;
// }
//---------------------------------------------
//LayoutParams方法
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - mLastX;
int offsetY = y - mLastY;
//示例程式碼的父View是LinearLayout
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetX;
layoutParams.topMargin = getTop() + offsetY;
//下面這兩句都可以使用,setLayoutParams也會呼叫requestLayout
// setLayoutParams(layoutParams);
requestLayout();
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
mLastX = x;
mLastY = y;
return true;
}
}