如何暂停画布以特定角度旋转2秒? [英] How to pause canvas from rotating for 2 secs at specific angles?

查看:89
本文介绍了如何暂停画布以特定角度旋转2秒?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个旋钮,但是我想将旋钮以特定角度停下来2秒钟.我想将其停在260f和-20f上.

I made a rotating knob ,but I want to stop the knob at specific angles for 2 seconds. I want to stop it on 260f and -20f.

有人可以建议怎么做吗?

Can anyone suggest how to do it ?

这是博客中的代码.我根据自己的要求进行了许多更改.

This is the code from a blog. I made many changes according to my requirements.

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) ? 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);
  }

  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);
  }
} 

推荐答案

我认为,这里的最终答案是通过扩展SurfaceView然后覆盖onDraw(Canvas canvas)

I think the ultimate answer here is to implement your own class by extending SurfaceView and then overriding onDraw( Canvas canvas )

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

You can then use the Canvas routines to render your control.

如果您使用google,还有很多很好的例子.

There are a lot of good examples out there if you google.

要开始初始化表面视图:

To get started initialize the surface view:

    // So things actually render
    setDrawingCacheEnabled(true);
    setWillNotDraw(false);
    setZOrderOnTop(true);

    // Controls the drawing thread.
    getHolder().addCallback(new CallbackSurfaceView());

重写onDraw并添加您的渲染例程.您可以将它们分层 随你去.

Override onDraw and add your rendering routines. You can layer them as you go.

public void onDraw(Canvas canvas) {

      // Always Draw
      super.onDraw(canvas);

      drawBackground(canvas);

      drawKnobIndentWell(canvas);

      drawKnob(canvas);

      drawKnobLED( canvas ); //etc....
}

回调和更新线程的示例:

An example of a Callback and an update thread:

/**
 * 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中自定义控件 自定义值.

If you decide to go this route you can customize your control from XML using custom values.

<com.killerknob.graphics.MultimeterVolumeControl
        android:id="@+id/volume_control"
        android:layout_below="@id/divider_one"
        android:background="@android:color/white"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:minHeight="60dp"
        custom:ledShadow="#357BBB"
        custom:ledColor="#357BBB"
        custom:knobBackground="@color/gray_level_13"
        custom:knobColor="@android:color/black"
        /> 

创建自定义控件时,请按其程序包名称进行引用. 您在/values下的资源文件中创建自定义变量,然后引用 他们在你班上.

When you create a custom control you reference it by its package name. You create custom variable in a resource file under /values and then reference them in your class.

此处有更多详细信息:

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

这可能比您想做的工作还要多,但是我认为您最终将获得更加专业的外观控制,并且动画会更加流畅.

This may be more work then you want to do, but I think you will end up with a more professional looking control and the animations will be smoother.

无论如何,它看起来是一个有趣的项目.祝你好运.

At any rate, looks like a fun project. Good Luck.

这篇关于如何暂停画布以特定角度旋转2秒?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆