public class TestActivity extends AppCompatActivity {
private ImageView imageView;
private ImageView imageView2;
private Context context;
//defalut旋转开始角度
private float dfFromDegrees = -90;
//旋转结束角度
private float dfToDegrees = 90;
private ObjectAnimator animator;
//动画类型
private String propertyName = "rotation";
//持续时间
private long duration = 3000;
//重复模式
int RepeatCount = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
context = TestActivity.this;
initView();
initAnimator();
animatorStart();
}
//初始化动画
private void initAnimator() {
animator = ObjectAnimator.ofFloat(imageView, propertyName, dfFromDegrees, dfToDegrees);
animator.setDuration(duration);
animator.setRepeatCount(RepeatCount);
animator.setRepeatMode(ValueAnimator.REVERSE);
}
private void initView() {
imageView = (ImageView) findViewById(R.id.image);
imageView2 = (ImageView) findViewById(R.id.image2);
imageView2.setVisibility(View.GONE);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
LogUtil.i("countAngle(ev):" + countAngle(ev));
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
LogUtil.i("ACTION_DOWN");
animatorCancel();
setImageView2TransLation(ev, true);
imageView.setRotation(countAngle(ev));
break;
case MotionEvent.ACTION_MOVE:
LogUtil.i("ACTION_MOVE");
animatorCancel();
imageView2.setVisibility(View.VISIBLE);
setImageView2TransLation(ev, true);
imageView.setRotation(countAngle(ev));
break;
case MotionEvent.ACTION_UP:
LogUtil.i("ACTION_UP");
imageView2.setVisibility(View.GONE);
setAnimatorDegrees(dfFromDegrees, dfToDegrees);
setImageView2TransLation(ev, false);
animatorStart();
break;
}
return super.dispatchTouchEvent(ev);
}
//计算点击角度
private float countAngle(MotionEvent event) {
//点击的坐标X
float clickX = event.getX();
//点击的坐标Y
float clickY = event.getY();
//imageView控件X坐标
float viewX = imageView.getX() + imageView.getPivotX();
float viewY = imageView.getY() + imageView.getPivotY();
return getRotationBetweenLines(viewX, viewY, clickX, clickY);
}
//设置控件2位置是否隐藏
private void setImageView2TransLation(MotionEvent ev, boolean isShow) {
imageView2.setTranslationX(ev.getX() - imageView2.getWidth() / 2);
imageView2.setTranslationY(ev.getY() - imageView2.getHeight());
imageView2.setVisibility(isShow ? View.VISIBLE : View.GONE);
}
//设置动画旋转角度
private void setAnimatorDegrees(float fromDegrees, float toDegrees) {
animator = ObjectAnimator.ofFloat(imageView, propertyName, fromDegrees, toDegrees);
animator.setDuration(3000);
animator.setRepeatCount(-1);
animator.setRepeatMode(ValueAnimator.REVERSE);
}
//开始动画
private void animatorStart() {
if (animator != null)
animator.start();
}
//关闭动画
private void animatorCancel() {
if (animator != null)
animator.cancel();
}
//centerX、centerY为公共点,xInView、yInView为触摸点的坐标
public int getRotationBetweenLines(float centerX, float centerY, float xInView, float yInView) {
double rotation = 0;
double k1 = (double) (centerY - centerY) / (centerX * 2 - centerX);
double k2 = (double) (yInView - centerY) / (xInView - centerX);
double tmpDegree = Math.atan((Math.abs(k1 - k2)) / (1 + k1 * k2)) / Math.PI * 180;
if (xInView > centerX && yInView < centerY) { //第一象限
rotation = 90 - tmpDegree;
} else if (xInView > centerX && yInView > centerY) //第二象限
{
rotation = 90 + tmpDegree;
} else if (xInView < centerX && yInView > centerY) { //第三象限
rotation = 270 - tmpDegree;
} else if (xInView < centerX && yInView < centerY) { //第四象限
rotation = 270 + tmpDegree;
} else if (xInView == centerX && yInView < centerY) {
rotation = 0;
} else if (xInView == centerX && yInView > centerY) {
rotation = 180;
}
return (int) rotation;
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="@mipmap/ic_launcher"
android:layout_centerInParent="true"
/>
<ImageView
android:id="@+id/image2"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="@mipmap/ic_launcher"
/>
</RelativeLayout>