这里用到了一些属性动画的知识和对屏幕坐标的知识,其实不是很难,给大家上个图。
然后代码呢其实就是一个Mainctivity,界面也就一个,我力图简单,只为你们服务,下面给出代码。
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements View.OnClickListener, View.OnTouchListener {
private TextView mRlMezi; //被我们控制的控件
private DisplayMetrics dm; //用来获取屏幕的宽高
private int lastX, lastY; //手指离开屏幕的坐标点
private static Boolean know = false; //用来处理每次把触碰事件当移动来处理还是当移动来处理
private float position1 = 0; //刚点击时的X坐标
private float position2 = 0; //手指离开屏幕的X坐标
private ValueAnimator animator1; //用来执行动画
private int l, b, r, t; //控件的位置参数
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRlMezi = (TextView) findViewById(R.id.rl_mezi);
dm = getResources().getDisplayMetrics();
//下面两个方法时关键,实际上我们使用的时候只需要把我们需要控制的控件添加这两个监听即可实现效果
mRlMezi.setOnTouchListener(this); //一个设置触碰监听
mRlMezi.setOnClickListener(this); //一个设置点击监听
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rl_mezi:
if (!know) {
Toast.makeText(this, "点我干嘛?", Toast.LENGTH_SHORT).show(); //这里我只打了一个Toast,但是实际上我们可以做更多的事,比如跳出一个对话框,或者进入另一个Activity什么的
}
break;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int ea = event.getAction();
final int screenWidth = dm.widthPixels; //获取屏宽
final int screenHeight = dm.heightPixels; //获取屏高
switch (v.getId()) {
case R.id.rl_mezi:
switch (ea) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
position1 = lastX;
know = false;
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
l = v.getLeft() + dx;
b = v.getBottom() + dy;
r = v.getRight() + dx;
t = v.getTop() + dy;
/*
* 下面用来处理超出屏幕范围
* */
if (l < 0) {
l = 0;
r = l + v.getWidth();
}
if (t < 0) {
t = 0;
b = t + v.getHeight();
}
if (r > screenWidth) {
r = screenWidth;
l = r - v.getWidth();
}
if (b > screenHeight) {
b = screenHeight;
t = b - v.getHeight();
}
v.layout(l, t, r, b);
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
v.postInvalidate();
break;
case MotionEvent.ACTION_UP:
position2 = (int) event.getRawX();
//对比两个移动的差距,如果大于4,我们认定移动了,即不可响应onClick事件,如果小于4,就可以响应
if (Math.abs(position2 - position1) > 4) {
know = true;
}
if (v.getLeft() + v.getWidth() / 2 > screenWidth / 2) {
startrightanimator(v.getX(), v.getY(), screenWidth - v.getLeft() - v.getWidth());
animator1.start();
} else {
startleftanimator(v.getX(), v.getY(), v.getLeft());
}
break;
}
default:
break;
}
return know;
}
//执行向左移动的动画
private void startleftanimator(final float x, final float y, final int postion) {
//我们用的是属性动画,只有属性动画才可以让控件移动并且响应位置也发生移动
animator1 = ValueAnimator.ofInt(0, postion);
animator1.setDuration(1000); //这里设置动画的时长
animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = Integer.valueOf(animation.getAnimatedValue().toString());
//注意下面的设置,只有一个地方是需要我们手动更改的,那就是:mRlMezi,使用的使用更改成我们需要控制的那个控件即可
mRlMezi.layout(-curValue + (int) x, (int) y, -curValue + (int) x + mRlMezi.getWidth(), mRlMezi.getHeight() + (int) y);
}
});
animator1.start(); //开始动画
}
//执行向右移动的动画
private void startrightanimator(final float x, final float y, final int postion) {
animator1 = ValueAnimator.ofInt(0, postion);
animator1.setDuration(1000);
animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = Integer.valueOf(animation.getAnimatedValue().toString());
mRlMezi.layout(curValue + (int) x, (int) y, curValue + (int) x + mRlMezi.getWidth(), mRlMezi.getHeight() + (int) y);
}
});
animator1.start();
}
}
注释很详细,下面给出我的DEMO:
http://download.csdn.net/download/wanxuedong/9896733