如何暂停canvas在特定角度旋转2秒?

我做了一个旋转旋钮,但我想在特定角度停止旋钮2秒钟。 我想在260f和-20f停止它。

任何人都可以建议怎么做?

这是博客的代码。 我根据自己的要求做了很多改变。

public class RotatoryKnobView extends ImageView { private float angle = -20f; private float theta_old=0f; private RotaryKnobListener listener; public interface RotaryKnobListener { public void onKnobChanged(float arg); } public void setKnobListener(RotaryKnobListener l ) { listener = l; } public RotatoryKnobView(Context context) { super(context); initialize(); } public RotatoryKnobView(Context context, AttributeSet attrs) { super(context, attrs); initialize(); } public RotatoryKnobView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initialize(); } private float getTheta(float x, float y) { float sx = x - (getWidth() / 2.0f); float sy = y - (getHeight() / 2.0f); float length = (float)Math.sqrt( sx*sx + sy*sy); float nx = sx / length; float ny = sy / length; float theta = (float)Math.atan2( ny, nx ); final float rad2deg = (float)(180.0/Math.PI); float thetaDeg = theta*rad2deg; return (thetaDeg  0) ? 1 : -1; angle += 5*direction; notifyListener(angle+20); break; } return true; } }); } private void notifyListener(float arg) { if (null!=listener) listener.onKnobChanged(arg); } protected void onDraw(Canvas c) {if(angle==257f){ try { synchronized (c) { c.wait(5000); angle=260f; } } catch (InterruptedException e) { } } else if(angle==-16f) { try { synchronized (c) { c.wait(5000); angle=-20f; } } catch (InterruptedException e) { } } else if(angle>260f) { angle=-20f; } else if(angle<-20f) { angle=260f; } else{ c.rotate(angle,getWidth()/2,getHeight()/2); } super.onDraw(c); } } 

Solutions Collecting From Web of "如何暂停canvas在特定角度旋转2秒?"

您可以设置固定角度并使用postDelayed在2秒后清除它。

  public class RotatoryKnobView extends ImageView { private float angle = -20f; private float theta_old=0f; private RotaryKnobListener listener; private Float fixedAngle; private float settleAngle; private Runnable unsetFixedAngle = new Runnable() { @Override public void run() { angle = settleAngle; fixedAngle = null; invalidate(); } }; public interface RotaryKnobListener { public void onKnobChanged(float arg); } public void setKnobListener(RotaryKnobListener l ) { listener = l; } public RotatoryKnobView(Context context) { super(context); initialize(); } public RotatoryKnobView(Context context, AttributeSet attrs) { super(context, attrs); initialize(); } public RotatoryKnobView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initialize(); } private float getTheta(float x, float y) { float sx = x - (getWidth() / 2.0f); float sy = y - (getHeight() / 2.0f); float length = (float)Math.sqrt( sx*sx + sy*sy); float nx = sx / length; float ny = sy / length; float theta = (float)Math.atan2( ny, nx ); final float rad2deg = (float)(180.0/Math.PI); float thetaDeg = theta*rad2deg; return (thetaDeg < 0) ? thetaDeg + 360.0f : thetaDeg; } public void initialize() { this.setImageResource(R.drawable.rotoron); setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { float x = event.getX(0); float y = event.getY(0); float theta = getTheta(x,y); switch(event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_POINTER_DOWN: theta_old = theta; break; case MotionEvent.ACTION_MOVE: invalidate(); float delta_theta = theta - theta_old; theta_old = theta; int direction = (delta_theta > 0) ? 1 : -1; angle += 5*direction; notifyListener(angle+20); break; } return true; } }); } private void notifyListener(float arg) { if (null!=listener) listener.onKnobChanged(arg); } void setFixedAngle(float angle, float settleAngle) { fixedAngle = angle; this.settleAngle = settleAngle; postDelayed(unsetFixedAngle, 2000); } protected void onDraw(Canvas c) { if(fixedAngle==null) { if (angle > 270) { setFixedAngle(270, -15); } else if (angle < -20f) { setFixedAngle(-20, 260); } } Log.d("angle", "angle: " + angle + " fixed angle: " + fixedAngle); c.rotate(fixedAngle == null ? angle : fixedAngle,getWidth()/2,getHeight()/2); super.onDraw(c); } } 

`

我认为这里的最终答案是通过扩展SurfaceView然后重写onDraw (Canvascanvas)来实现自己的类。

然后,您可以使用Canvas例程来呈现控件。

如果你谷歌,有很多很好的例子。

要开始初始化曲面视图:

  // So things actually render setDrawingCacheEnabled(true); setWillNotDraw(false); setZOrderOnTop(true); // Controls the drawing thread. getHolder().addCallback(new CallbackSurfaceView()); 

覆盖onDraw并添加渲染例程。 您可以随时分层。

 public void onDraw(Canvas canvas) { // Always Draw super.onDraw(canvas); drawBackground(canvas); drawKnobIndentWell(canvas); drawKnob(canvas); drawKnobLED( canvas ); //etc.... } 

回调和更新线程的示例:

 /** * This is the drawing callback. * It handles the creation and destruction of the drawing thread when the * surface for drawing is created and destroyed. */ class CallbackSurfaceView implements SurfaceHolder.Callback { Thread threadIndeterminant; RunnableProgressUpdater runnableUpdater; boolean done = false; /** * Kills the running thread. */ public void done() { done = true; if (null != runnableUpdater) { runnableUpdater.done(); } } /** * Causes the UI to render once. */ public void needRedraw() { if (runnableUpdater != null) { runnableUpdater.needRedraw(); } } /** * When the surface is created start the drawing thread. * @param holder */ @Override public void surfaceCreated(SurfaceHolder holder) { if (!done) { threadIndeterminant = new Thread(runnableUpdater = new RunnableProgressUpdater()); threadIndeterminant.start(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } /** * When the surface is destroyed stop the drawing thread. * @param holder */ @Override public void surfaceDestroyed(SurfaceHolder holder) { if (null != runnableUpdater) { runnableUpdater.done(); threadIndeterminant = null; runnableUpdater = null; } } } /** * This is the runnable for the drawing operations. It is started and stopped by the callback class. */ class RunnableProgressUpdater implements Runnable { boolean surfaceExists = true; boolean needRedraw = false; public void done() { surfaceExists = false; } public void needRedraw() { needRedraw = true; } @Override public void run() { canvasDrawAndPost(); while (surfaceExists) { // Renders continuously during a download operation. // Otherwise only renders when requested. // Necessary so that progress bar and cirlce activity update. if (syncContext.isRunning()) { canvasDrawAndPost(); needRedraw = true; } else if (needRedraw) { canvasDrawAndPost(); needRedraw = false; } try { Thread.sleep(100); } catch (InterruptedException e) { // Don't care } } // One final update canvasDrawAndPost(); } /** * Routine the redraws the controls on each loop. */ private synchronized void canvasDrawAndPost() { Canvas canvas = getHolder().lockCanvas(); if (canvas != null) { try { draw(canvas); } finally { getHolder().unlockCanvasAndPost(canvas); } } } } 

如果您决定使用此路线,则可以使用自定义值从XML自定义控件。

  

创建自定义控件时,可以通过其包名引用它。 您可以在/ values下的资源文件中创建自定义variables,然后在您的类中引用它们。

更多细节在这里:

http://developer.android.com/training/custom-views/create-view.html

这可能是你想要做的更多工作,但我认为你最终将拥有更专业的控制,animation将更加顺畅。

无论如何,看起来像一个有趣的项目。 祝你好运。