我需要旋转一个有一些按钮的视图。通过手指移动,视图也应该随之与其子视图一起旋转。
直到现在我已经实现了这个:
private RelativeLayout mCircle;
private double mCurrAngle = 0;
private double mPrevAngle = 0;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCircle = (RelativeLayout) findViewById(R.id.circle);
mCircle.setOnTouchListener(this); // Your activity should implement
// OnTouchListener
}
@Override
public boolean onTouch(View v, MotionEvent event) {
final float xc = mCircle.getWidth() / 2;
final float yc = mCircle.getHeight() / 2;
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mCircle.clearAnimation();
mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
}
case MotionEvent.ACTION_MOVE: {
mPrevAngle = mCurrAngle;
mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
mCircle.setRotation((float) (mPrevAngle - mCurrAngle));
animate(mPrevAngle, mCurrAngle, 0);
break;
}
case MotionEvent.ACTION_UP: {
mPrevAngle = mCurrAngle = 0;
break;
}
}
return true;
}
private void animate(double fromDegrees, double toDegrees,
long durationMillis) {
final RotateAnimation rotate = new RotateAnimation((float) fromDegrees,
(float) toDegrees, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(durationMillis);
rotate.setFillEnabled(true);
rotate.setFillAfter(true);
mCircle.startAnimation(rotate);
}
但它不顺畅,因此无法实施。
感谢。
答案 0 :(得分:2)
首先,不要使用动画,因为你想在手指移动时直接改变视图。
然后,对于计算,将OnTouchListener附加到要旋转的视图的父视图要容易得多,因此旋转本身不会修改触摸事件的坐标。
如果您的父视图的ID为“@ + id / root”:
,则以下是代码private RelativeLayout mRoot;
private RelativeLayout mCircle;
int i = 0;
float viewRotation;
double fingerRotation;
double newFingerRotation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRoot = (RelativeLayout)findViewById(R.id.root);
mCircle = (RelativeLayout) findViewById(R.id.circle);
mRoot.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
final float xc = mRoot.getWidth()/2;
final float yc = mRoot.getHeight()/2;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
viewRotation = mCircle.getRotation();
fingerRotation = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
newFingerRotation = Math.toDegrees(Math.atan2(x - xc, yc - y));
mCircle.setRotation((float)(viewRotation + newFingerRotation - fingerRotation));
break;
case MotionEvent.ACTION_UP:
fingerRotation = newFingerRotation = 0.0f;
break;
}
return true;
}
答案 1 :(得分:1)
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (action) {
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_DOWN:
rotateX = event.getRawX();
rotateY = event.getRawY();
centerX = view.getX() + ((View) getParent()).getX() + (float) view.getWidth() / 2;
centerY = view.getY() + statusBarHeight + (float) view.getHeight() / 2;
break;
case MotionEvent.ACTION_MOVE:
newRotateX = event.getRawX();
newRotateY = event.getRawY();
double angle = Math.atan2(event.getRawY() - centerY, event.getRawX() - centerX) * 180 / Math.PI;
view.setRotation((float) angle - 45);
rotateX = newRotateX;
rotateY = newRotateY;
}
}
return true;
}
};