Android-如何旋转多个2D图形对象
我试图在屏幕上旋转两个圆圈。按下按钮时,一个圆圈顺时针旋转,另一个圆圈逆时针旋转。两者都将旋转90度,然后停止,直到单击下一个按钮。Android-如何旋转多个2D图形对象,android,2d,Android,2d,我试图在屏幕上旋转两个圆圈。按下按钮时,一个圆圈顺时针旋转,另一个圆圈逆时针旋转。两者都将旋转90度,然后停止,直到单击下一个按钮。 工作正常,但看起来很糟糕。不是同时旋转,而是先旋转一圈,然后旋转第二圈。 我读过关于动画的书,但是我找到的所有例子都展示了如何旋转整个画布。可能我看的地方不对,有一种方法可以将动画以某种方式指定给对象。 我在下面添加了我的代码。我为它不是一个真正的SSCE而道歉,但当我的自定义SurfaceView是主活动下的一个内部类时,我出现了错误 任何关于如何正确执行此操作
工作正常,但看起来很糟糕。不是同时旋转,而是先旋转一圈,然后旋转第二圈。
我读过关于动画的书,但是我找到的所有例子都展示了如何旋转整个画布。可能我看的地方不对,有一种方法可以将动画以某种方式指定给对象。
我在下面添加了我的代码。我为它不是一个真正的SSCE而道歉,但当我的自定义SurfaceView是主活动下的一个内部类时,我出现了错误
任何关于如何正确执行此操作的建议或指导都非常感谢。 活动 自定义表面视图
package sscce.android.rotation;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private Circle circle1;
private Circle circle2;
private DrawThread drawThread;
public MySurfaceView(Context context) {
super(context);
initialize();
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
private void initialize() {
getHolder().addCallback(this);
drawThread = new DrawThread(getHolder(), this);
setFocusable(true);
}
public void surfaceCreated(SurfaceHolder holder) {
circle1 = new Circle(getWidth() / 2, getHeight() / 2, 50);
circle2 = new Circle(getWidth() / 2, getHeight() / 2, 80);
drawThread.setRunning(true);
drawThread.start();
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
drawThread.setRunning(false);
while (retry) {
try {
drawThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
public void onDraw(Canvas canvas) {
circle2.onDraw(canvas);
circle1.onDraw(canvas);
}
public void rotate(boolean clockWise) {
Rotator rotator1 = new Rotator(circle1, clockWise);
Rotator rotator2 = new Rotator(circle2, !clockWise);
rotator1.run();
rotator2.run();
}
private class Circle {
private RectF rectF;
private int rotationAngle = 0;
MyPaint bluePaint = new MyPaint(1, Paint.Cap.SQUARE, Paint.Style.FILL,
Color.BLUE);
MyPaint redPaint = new MyPaint(1, Paint.Cap.SQUARE, Paint.Style.FILL,
Color.RED);
MyPaint yellowPaint = new MyPaint(1, Paint.Cap.SQUARE,
Paint.Style.FILL, Color.YELLOW);
MyPaint greenPaint = new MyPaint(1, Paint.Cap.SQUARE, Paint.Style.FILL,
Color.GREEN);
MyPaint borderPaint = new MyPaint(3, Paint.Cap.SQUARE,
Paint.Style.STROKE, Color.WHITE);
public Circle(int centerX, int centerY, int radius) {
rectF = new RectF(new Rect(centerX - radius, centerY - radius,
centerX + radius, centerY + radius));
}
public void rotateClockwise() {
for (int i = 0; i < 90; i++) {
rotationAngle++;
if (rotationAngle == 360) {
rotationAngle = 0;
return;
}
try {
Thread.sleep(20, 0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void rotateCounterClockwise() {
for (int i = 0; i < 90; i++) {
rotationAngle--;
if (rotationAngle == 0) {
rotationAngle = 360;
return;
}
try {
Thread.sleep(20, 0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void onDraw(Canvas canvas) {
canvas.drawArc(rectF, (0 + rotationAngle) % 360, 90, true,
bluePaint);
canvas.drawArc(rectF, (90 + rotationAngle) % 360, 90, true,
redPaint);
canvas.drawArc(rectF, (180 + rotationAngle) % 360, 90, true,
yellowPaint);
canvas.drawArc(rectF, (270 + rotationAngle) % 360, 90, true,
greenPaint);
canvas.drawArc(rectF, 0, 360, true, borderPaint);
}
private class MyPaint extends Paint {
public MyPaint(int strokeWidth, Paint.Cap cap, Paint.Style style,
int color) {
setStrokeWidth(strokeWidth);
setAntiAlias(true);
setStrokeCap(cap);
setStyle(style);
setColor(color);
}
}
}
private class Rotator extends Thread {
private Circle circle;
private boolean clockwise;
public Rotator(Circle circle, boolean clockwise) {
this.circle = circle;
this.clockwise = clockwise;
}
@Override
public void run() {
if (clockwise) {
circle.rotateClockwise();
} else {
circle.rotateCounterClockwise();
}
}
}
private class DrawThread extends Thread {
private SurfaceHolder surfaceHolder;
private MySurfaceView surfaceView;
private boolean run = false;
public DrawThread(SurfaceHolder surfaceHolder, MySurfaceView surfaceView) {
this.surfaceHolder = surfaceHolder;
this.surfaceView = surfaceView;
run = false;
}
public void setRunning(boolean run) {
Log.d("setRunning@DrawThread", "Run status is " + run);
this.run = run;
}
@Override
public void run() {
Canvas canvas = null;
while (run) {
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
surfaceView.onDraw(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
}
包sscce.android.rotation;
导入android.content.Context;
导入android.content.DialogInterface;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Rect;
导入android.graphics.RectF;
导入android.util.AttributeSet;
导入android.util.Log;
导入android.view.SurfaceHolder;
导入android.view.SurfaceView;
公共类MySurfaceView扩展了SurfaceView实现
SurfaceHolder,回拨{
私人圈子1;
私人圈子2;
专用拉丝;
公共MySurfaceView(上下文){
超级(上下文);
初始化();
}
公共MySurfaceView(上下文、属性集属性){
超级(上下文,attrs);
初始化();
}
公共MySurfaceView(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
初始化();
}
私有void初始化(){
getHolder().addCallback(此);
drawThread=新的drawThread(getHolder(),this);
设置聚焦(真);
}
已创建的公共空白表面(表面持有人){
circle1=新圆(getWidth()/2,getHeight()/2,50);
circle2=新圆(getWidth()/2,getHeight()/2,80);
drawThread.setRunning(真);
drawThread.start();
}
公共无效表面更改(表面更改arg0、int arg1、int arg2、int arg3){
//TODO自动生成的方法存根
}
公共空间表面已覆盖(表面层arg0){
布尔重试=真;
drawThread.setRunning(假);
while(重试){
试一试{
drawThread.join();
重试=错误;
}捕捉(中断异常e){
//我们会一次又一次的尝试。。。
}
}
}
公共空白onDraw(画布){
圆圈2.onDraw(帆布);
圆圈1.onDraw(帆布);
}
公共空心旋转(布尔值顺时针){
旋转器旋转器1=新旋转器(圆圈1,顺时针);
旋转器旋转器2=新旋转器(圆圈2,!顺时针);
rotator1.run();
rotator2.run();
}
私人阶级圈子{
私有RectF-RectF;
私有整数旋转角度=0;
MyPaint bluePaint=新的MyPaint(1,Paint.Cap.SQUARE,Paint.Style.FILL,
颜色(蓝色);
MyPaint redPaint=新的MyPaint(1,Paint.Cap.SQUARE,Paint.Style.FILL,
颜色(红色);
MyPaint yellowPaint=新MyPaint(1,Paint.Cap.SQUARE,
油漆、样式、填充、颜色、黄色);
MyPaint greenPaint=新MyPaint(1,Paint.Cap.SQUARE,Paint.Style.FILL,
颜色(绿色);
MyPaint borderPaint=新的MyPaint(3,Paint.Cap.SQUARE,
油漆、样式、笔划、颜色、白色);
公共圆(整数中心X、整数中心Y、整数半径){
rectF=新rectF(新Rect(centerX-半径,centerY-半径,
中心X+半径,中心Y+半径);
}
公共空间按顺时针旋转(){
对于(int i=0;i<90;i++){
旋转角度++;
如果(旋转角度==360){
旋转角度=0;
返回;
}
试一试{
睡眠(20,0);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
公共空间旋转逆时针(){
对于(int i=0;i<90;i++){
旋转角--;
如果(旋转角度==0){
旋转角度=360;
返回;
}
试一试{
睡眠(20,0);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
公共空白onDraw(画布){
画布绘制弧(矩形,(0+旋转角度)%360,90,真,
蓝漆);
画布绘制弧(矩形,(90+旋转角度)%360,90,真,
红漆);
画布绘制弧(矩形,(180+旋转角度)%360,90,真,
黄色油漆);
画布绘制弧(矩形,(270+旋转角度)%360,90,真,
绿色油漆);
画布.drawArc(rectF,0,360,true,borderPaint);
}
私有类MyPaint扩展了Paint{
公共MyPaint(int strokeWidth、Paint.Cap、Paint.Style、,
int颜色){
设置行程宽度(行程宽度);
setAntiAlias(真);
调整行程盖(盖);
设置样式(样式);
设置颜色(颜色);
}
}
}
私有类旋转器扩展线程{
私人圈子;
私有布尔顺时针;
公共旋转器(圆形,布尔顺时针){
package sscce.android.rotation;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private Circle circle1;
private Circle circle2;
private DrawThread drawThread;
public MySurfaceView(Context context) {
super(context);
initialize();
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
private void initialize() {
getHolder().addCallback(this);
drawThread = new DrawThread(getHolder(), this);
setFocusable(true);
}
public void surfaceCreated(SurfaceHolder holder) {
circle1 = new Circle(getWidth() / 2, getHeight() / 2, 50);
circle2 = new Circle(getWidth() / 2, getHeight() / 2, 80);
drawThread.setRunning(true);
drawThread.start();
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
drawThread.setRunning(false);
while (retry) {
try {
drawThread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
public void onDraw(Canvas canvas) {
circle2.onDraw(canvas);
circle1.onDraw(canvas);
}
public void rotate(boolean clockWise) {
Rotator rotator1 = new Rotator(circle1, clockWise);
Rotator rotator2 = new Rotator(circle2, !clockWise);
rotator1.run();
rotator2.run();
}
private class Circle {
private RectF rectF;
private int rotationAngle = 0;
MyPaint bluePaint = new MyPaint(1, Paint.Cap.SQUARE, Paint.Style.FILL,
Color.BLUE);
MyPaint redPaint = new MyPaint(1, Paint.Cap.SQUARE, Paint.Style.FILL,
Color.RED);
MyPaint yellowPaint = new MyPaint(1, Paint.Cap.SQUARE,
Paint.Style.FILL, Color.YELLOW);
MyPaint greenPaint = new MyPaint(1, Paint.Cap.SQUARE, Paint.Style.FILL,
Color.GREEN);
MyPaint borderPaint = new MyPaint(3, Paint.Cap.SQUARE,
Paint.Style.STROKE, Color.WHITE);
public Circle(int centerX, int centerY, int radius) {
rectF = new RectF(new Rect(centerX - radius, centerY - radius,
centerX + radius, centerY + radius));
}
public void rotateClockwise() {
for (int i = 0; i < 90; i++) {
rotationAngle++;
if (rotationAngle == 360) {
rotationAngle = 0;
return;
}
try {
Thread.sleep(20, 0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void rotateCounterClockwise() {
for (int i = 0; i < 90; i++) {
rotationAngle--;
if (rotationAngle == 0) {
rotationAngle = 360;
return;
}
try {
Thread.sleep(20, 0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void onDraw(Canvas canvas) {
canvas.drawArc(rectF, (0 + rotationAngle) % 360, 90, true,
bluePaint);
canvas.drawArc(rectF, (90 + rotationAngle) % 360, 90, true,
redPaint);
canvas.drawArc(rectF, (180 + rotationAngle) % 360, 90, true,
yellowPaint);
canvas.drawArc(rectF, (270 + rotationAngle) % 360, 90, true,
greenPaint);
canvas.drawArc(rectF, 0, 360, true, borderPaint);
}
private class MyPaint extends Paint {
public MyPaint(int strokeWidth, Paint.Cap cap, Paint.Style style,
int color) {
setStrokeWidth(strokeWidth);
setAntiAlias(true);
setStrokeCap(cap);
setStyle(style);
setColor(color);
}
}
}
private class Rotator extends Thread {
private Circle circle;
private boolean clockwise;
public Rotator(Circle circle, boolean clockwise) {
this.circle = circle;
this.clockwise = clockwise;
}
@Override
public void run() {
if (clockwise) {
circle.rotateClockwise();
} else {
circle.rotateCounterClockwise();
}
}
}
private class DrawThread extends Thread {
private SurfaceHolder surfaceHolder;
private MySurfaceView surfaceView;
private boolean run = false;
public DrawThread(SurfaceHolder surfaceHolder, MySurfaceView surfaceView) {
this.surfaceHolder = surfaceHolder;
this.surfaceView = surfaceView;
run = false;
}
public void setRunning(boolean run) {
Log.d("setRunning@DrawThread", "Run status is " + run);
this.run = run;
}
@Override
public void run() {
Canvas canvas = null;
while (run) {
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
surfaceView.onDraw(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<sscce.android.rotation.MySurfaceView
android:id="@+id/surfaceView1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<Button
android:id="@+id/btnClockwise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clockwise" />
<Button
android:id="@+id/btnCounterClockwise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Counter Clockwise" />
</LinearLayout>
</LinearLayout>
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(cwRotation);
//draw first circle here
canvas.restore();
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(ccwRotation);
//draw second circle here
canvas.restore();