一、前言
在Android开发中,大家可能会遇到控件会随着点击或者滑动而改变,控件的滑动和大小改变上一章的animation动画效果已经讲过了,那么如何实现控件随着手势的移动而移动呢?
二、概述
1、在手指接触到屏幕以后会产生一系列的事件,而这些事件可以通过MotionEvent和TouchSlop进行监听,典型的事件有如下几种:
(1)ACTION_DOWN:手指刚接触屏幕的事件
(2)ACTION_MOVE:手指在屏幕移动会执行的方法
(3)ACTION_UP:手指从屏幕上松开的时候执行的方法。
通过以上三个方法加上画面移动效果就可以实现随手势移动而控件移动的效果。其中两种实现方式如下:
三、scroller的实现方式
1、scroller是弹性滑动对象,scroller移动是框架中的内容移动(例如定义一个button,移动button时只会是button内的文字移动)就是将一个view移动到另一个位置时会有过渡效果,scroller有两个方法ScrollTo和ScrollBy。
ScrollTo:将view移动到指定位置
ScrollBy:将view移动的距离。具体使用方法和效果图如下:
2、可以看到移动时只能在指定的框内移动,具体代码如下:
private void initView(){
heart_slide_id=findViewById(R.id.heart_slide_id);
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
heart_slide_id.measure(spec, spec);
measuredWidth = heart_slide_id.getMeasuredWidth();
measuredHeight = heart_slide_id.getMeasuredHeight();
}
/*
* 初始化点击事件
* */
private void initOnclick(){
heart_slide_id.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
//手指按下时执行的方法
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//触摸点相对于屏幕原点的x坐标,触摸点相对于其所在组件原点的x坐标event.getX()
int mLastX=(int)event.getRawX()-measuredWidth;
//触摸点相对于屏幕原点的x坐标有,减36是减去屏幕上方信息栏的高度
int mLastY=(int)event.getRawY()-measuredHeight-36;
//通过Scroller的方式
scroller=new Scroller(getApplicationContext());
//将框架移动到指定x,y轴的位置,scroller和动画效果的坐标不太一样,参数值是-的。
heart_slide_id.scrollTo(-mLastX,-mLastY);
startX=mLastX;
startY=mLastY;
break;
case MotionEvent.ACTION_UP:
break;
}
//如果返回true,则将不会继续调用onTouchEvent方法
return true;
}
});
}
四、动画animation的实现方式
1、如果不了解动画animation的,可以查看我的上一篇博客。动画效果实现就可以随机指定屏幕上的位置进行移动,效果如下:
2、实现代码如下:
public class MainSlideActivity extends BaseActivity implements View.OnTouchListener{
private ImageView heart_slide_id;
private int startX=0;
private int startY=0;
private Scroller scroller;
private int measuredWidth;
private int measuredHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_slide_layout);
initView();
}
private void initView(){
heart_slide_id=findViewById(R.id.heart_slide_id);
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
heart_slide_id.measure(spec, spec);
measuredWidth = heart_slide_id.getMeasuredWidth();
measuredHeight = heart_slide_id.getMeasuredHeight();
heart_slide_id.setOnTouchListener(this);
}
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
//手指按下时执行的方法
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//触摸点相对于屏幕原点的x坐标,触摸点相对于其所在组件原点的x坐标event.getRawX()
int mLastX=(int)event.getRawX()-measuredWidth;
//触摸点相对于屏幕原点的x坐标有,减36是减去屏幕上方信息栏的高度
int mLastY=(int)event.getRawY()-measuredHeight-36;
/* //通过Scroller的方式
scroller=new Scroller(getApplicationContext());
//将框架移动到指定x,y轴的位置,scroller和动画效果的坐标不太一样,参数值是-的。
heart_slide_id.scrollTo(-mLastX,-mLastY);*/
//延X轴移动
ObjectAnimator animator2=ObjectAnimator.ofFloat(heart_slide_id,"translationX",startX,mLastX);
animator2.setDuration(50);
//延y轴移动,起始位置和结束位置
ObjectAnimator animator3=ObjectAnimator.ofFloat(heart_slide_id,"translationY",startY,mLastY);
animator3.setDuration(50);
AnimatorSet set =new AnimatorSet();
set.play(animator2);
set.play(animator3);
set.start();
startX=mLastX;
startY=mLastY;
break;
case MotionEvent.ACTION_UP:
heart_slide_id.performClick();
break;
}
return true;
}
}