实现滑动的基本思想:
- 当触摸View时,系统记下当前的坐标
- 当手指移动时,系统记下当前移动点的坐标
- 从而获取了一个偏移量
- 通过这个偏移量修改这个View的坐标
即可实现滑动的过程
要实现的效果如下:
方法一:layout方法
直接采用了基本思想:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
* Created by feathers on 16-11-15.
*/
public class MyView extends ImageView {
private int downX;
private int downY;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 1. 记录按下时的坐标
downX = (int) event.getRawX();
downY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
// 2. 获取发生移动时的坐标
int moveX = (int) event.getRawX();
int moveY = (int) event.getRawY();
// 3. 获取偏移量
int offsetX = moveX - downX;
int offsetY = moveY - downY;
Log.i("logi", "offsetX" + offsetX);
Log.i("logi", "offsetY" + offsetY);
Log.i("logi", "offsetX + getLeft" + offsetX + getLeft());
Log.i("logi", "offsetY + getTop" + offsetY + getTop());
// 4. 重新为view布局
this.layout(getLeft()+offsetX,
getTop()+offsetY,
getRight()+offsetX,
getBottom()+offsetY);
// 初始化downX和Y,以方便下次计算偏移量
// 注意:这个偏移量第一次是按下与移动的差值,而第二次往后就是上次移动的和当前的位置的差值
downX = (int) event.getRawX();
downY = (int) event.getRawY();
break;
}
return true;
}
}
方法二:offsetLeftAndRight()和offsetTopAndBottom()
这是Android系统为我们提供的已经封装好的API,主要用于左右和上下移动
重要代码如下:
将
// 4. 重新为view布局
this.layout(getLeft()+offsetX,
getTop()+offsetY,
getRight()+offsetX,
getBottom()+offsetY);
替换为
offsetLeftAndRight(offsetX);
offsetTopAndBottom(offsetY);
即可
方法三:LayoutParams
设置LayoutParams,修改leftmargin和topmargin属性,从而完成滑动
注意:
1. View的LayoutParams与父ViewGroup有关,如果父控件是LinearLayout,则必须使用LinearLayout.LayoutParams(或者直接使用ViewGroup.LayoutParams)
2. leftMargin和topMargin是相对与父控件的值,如果父控件中设置了padding,则offset的计算也要对padding进行处理,否则出现异常
同上一个方法相同只需替换第4步为以下代码即可:
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetX;
layoutParams.topMargin = getTop() + offsetY;
this.setLayoutParams(layoutParams);