Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在特定角度暂停画布旋转2秒?_Android_Math_Layout_View_Rotation - Fatal编程技术网

Android 如何在特定角度暂停画布旋转2秒?

Android 如何在特定角度暂停画布旋转2秒?,android,math,layout,view,rotation,Android,Math,Layout,View,Rotation,我做了一个旋转旋钮,但我想在特定角度停止旋钮2秒钟。我想停在260f和-20f 有人能建议怎么做吗 这是来自博客的代码。我根据我的要求做了很多改变 public class RotatoryKnobView extends ImageView { private float angle = -20f; private float theta_old=0f; private RotaryKnobListener listener; public interface Rota

我做了一个旋转旋钮,但我想在特定角度停止旋钮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) ? 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);
  }
} 
公共类RotatoryKnobView扩展了ImageView{
专用浮动角度=-20f;
私有浮点θ_old=0f;
私人RotaryKnobListener监听器;
公共接口RotaryKnobListener{
更改后的公共无效(浮动参数);
}
公共无效设置Knoblistener(RotaryKnobListener l)
{
监听器=l;
}
公共旋转KnobView(上下文){
超级(上下文);
初始化();
}
公共旋转KnobView(上下文、属性集属性)
{
超级(上下文,attrs);
初始化();
}
公共旋转KnobView(上下文上下文、属性集属性、int-defStyle)
{
超级(上下文、属性、定义样式);
初始化();
}
私有浮点getTheta(浮点x,浮点y)
{
浮点sx=x-(getWidth()/2.0f);
float sy=y-(getHeight()/2.0f);
浮点长度=(浮点)数学sqrt(sx*sx+sy*sy);
浮动nx=sx/长度;
浮动ny=sy/长度;
浮点θ=(浮点)数学atan2(ny,nx);
最终浮点数rad2deg=(浮点数)(180.0/Math.PI);
浮点数θ=θ*rad2deg;
返回(标记<0)?标记+360.0f:标记;
}
公共无效初始化()
{
这个.setImageResource(R.drawable.rotoron);
setOnTouchListener(新的OnTouchListener()
{
@凌驾
公共布尔onTouch(视图v,运动事件){
float x=event.getX(0);
float y=event.getY(0);
浮点θ=getTheta(x,y);
开关(event.getAction()&MotionEvent.ACTION\u掩码)
{
case MotionEvent.ACTION\u指针\u向下:
θ=θ;
打破
case MotionEvent.ACTION\u移动:
使无效();
浮动增量θ=θ-θ旧;
θ=θ;
int方向=(δθ>0)?1:-1;
角度+=5*方向;
(角度+20);
打破
}
返回true;
}
});
}
私有void notifyListener(浮点参数)
{
if(null!=侦听器)
onKnobChanged(arg);
}
受保护的void onDraw(画布c)
{如果(角度==257f){
试一试{
已同步(c){
c、 等待(5000);
角度=260f;
}
}捕捉(中断异常e){
}
}
否则如果(角度==-16f)
{
试一试{
已同步(c){
c、 等待(5000);
角度=-20f;
}
}捕捉(中断异常e){
}
}
其他的
如果(角度>260f)
{
角度=-20f;
}

else if(angle我认为这里的最终答案是通过扩展
SurfaceView
然后重写
onDraw
(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自定义控件 自定义值

<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下的资源文件中创建自定义变量,然后引用 他们在你们班上

详情如下:

这可能是更多的工作,然后你想做的,但我认为你最终会有一个更专业的外观控制和动画将更加顺利


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

你可以设置一个固定角度,并在2秒后使用postDelayed清除它

    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);
    }
}
公共类RotatoryKnobView扩展了ImageView{
专用浮动角度=-20f;
私有浮点θ_old=0f;
私人RotaryKnobListener监听器;
私人浮动固定角;
私人浮动结算;
private Runnable unfixedangle=new Runnable(){
@凌驾
公开募捐{
角度=沉降角;
fixedAngle=null;
使无效();
}
};
公共接口RotaryKnobListener{
更改后的公共无效(浮动参数);
}
公共无效设置Knoblistener(RotaryKnobListener l)
{
监听器=l;
}
公共旋转KnobView(上下文){
超级(上下文);
初始化();
}
公共旋转KnobView(上下文、属性集属性)
{
超级(上下文,attrs);
初始化();
}
公共旋转KnobView(上下文上下文、属性集属性、int-defStyle)
{
超级(上下文、属性、定义样式);
初始化();
}
私有浮点getTheta(浮点x,浮点y)
{
浮点sx=x-(getWidth()/2.0f);
float sy=y-(getHeight()/2.0f);
浮点长度=(浮点)数学sqrt(sx*sx+sy*sy);
浮动nx=sx/长度;
浮动ny=sy/长度;
浮点θ=(浮点)数学atan2(ny,nx);
最终浮点数rad2deg=(浮点数)(180.0/Math.PI);
浮点数θ=θ*rad2deg;
返回(标记<0)?标记+360.0f:标记;
}
公共无效初始化()
{
这个.setImageResource(R.drawable.rotoron);
setOnTouchListener(新的OnTouchListener()
{
@凌驾
公共布尔onTouch(视图v,运动事件){
float x=event.getX(0);
float y=event.getY(0);
浮点θ=getTheta(x,y);
开关(event.getAction()&MotionEvent.ACTION\u掩码)
{
case MotionEvent.ACTION\u指针\u向下:
θ=θ;
打破
case MotionEvent.ACTION\u移动: