2017-02-13 195 views
1

我想创建一个平滑更改背景颜色的小动画。我的问题是,它只显示最后一个值(100,这意味着它直接进入红色背景)。我不知道为什么我创建while循环不具体化的每一个值(所以它会显示一个平稳彩色动画)虽然循环:更改背景颜色

新代码(几乎工作,但IDK如何停止动画)

imageButton_info.setOnClickListener(new View.OnClickListener(){ 

     @Override 
     public void onClick(View v){ 


       final Handler handler = new Handler(); 

       Runnable ChangeBackgroundRunnable = new Runnable() { 

        @Override 
        public void run() { 
         number++; 
         float[] hsvColor = {0, 1, 1}; 
         hsvColor[0] = 360f * number/100; 
         color.setBackgroundColor(Color.HSVToColor(hsvColor)); 

         handler.postDelayed(this, 80); 
         if (number >=100) 
          number = 1; 

        } 
       }; 
       number = 0; 
       handler.removeCallbacks(ChangeBackgroundRunnable); 
       handler.postDelayed(ChangeBackgroundRunnable, 0); 

     } 
    }); 

代码:

public void onClick(View v){ 

      try { 
       while (number<=100) { 

         number=number+1; 

         float[] hsvColor = {0, 1, 1}; 
         hsvColor[0] = 360f * number/100; 
         color.setBackgroundColor(Color.HSVToColor(hsvColor)); 

         Thread.sleep(10); 
       } 
      }catch(Exception e){ 

       //New exception 
       Log.e("Camera Error!",e.getMessage()); 

      } 

感谢您提前你的答案......

回答

0

包裹由@加布 - sechan和@杰西 - 巴斯发布

ValueAnimator支持设备SDK上面HONEYCOMB的答案。因此,在SDK级别下面,我们将使用@ gabe-sechan建议。检查下面的代码。

 
    private void executeBackgroundChange() { 
     // Handler and runnable to run the animation in devices sdk below honeycomb. 
     mHandler = new Handler(); 
     mChangeBackgroundRunnable = new Runnable() { 
      @Override 
      public void run() { 
       number++; 

       float[] hsvColor = {0, 1, 1}; 
       hsvColor[0] = 360f * number/100; 
       mContainer.setBackgroundColor(Color.HSVToColor(hsvColor)); 

       mHandler.postDelayed(this, 500); 
       if (number == 100) 
        number = 0; 
      } 
     }; 
     number = 0; 
     mHandler.removeCallbacks(mChangeBackgroundRunnable); 
     mHandler.postDelayed(mChangeBackgroundRunnable, 0); 
    } 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    private void executeBackgroundChangeUsingValueAnimator() { 
     colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), getResources().getColor(R.color.red), getResources().getColor(R.color.blue)); 
     colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(final ValueAnimator animator) { 
       mContainer.setBackgroundColor((Integer) animator.getAnimatedValue()); 
      } 
     }); 
     colorAnimation.setRepeatCount(ValueAnimator.INFINITE); 
     colorAnimation.setDuration(10 * 1000); 
     colorAnimation.start(); 
    } 

添加下面的方法,并停止动画,点击某个方法调用下面的方法。

 
    private void stopBackgroundChangeAnimation() { 
     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { 
      if (colorAnimation != null && colorAnimation.isRunning()) 
       colorAnimation.end(); 
     } else { 
      if (mHandler != null && mChangeBackgroundRunnable != null) 
       mHandler.removeCallbacks(mChangeBackgroundRunnable); 
     } 
    } 

查看github project以供参考。

+0

感谢这个答案,我都试过Gabe的和您的建议,它的工作近乎完美。我现在唯一的问题是,我不知道如何停止动画(我正在使用图像按钮)。你知道我怎么可以阻止它点击(我已经尝试创建一个while循环,但动画不起作用)? – Nick88

+0

我很遗憾地尝试过它不起作用,但是感谢您的支持。 – Nick88

1

当你在UI改变的东西,这不是不会立即发生。相反,它会在UI线程上向Looper发布消息。当控制返回到活套(当你完成框架调用的任何函数时),它将处理Looper上的所有消息,直到它最终处理重绘请求。然后它会画。因此,如果您在onClick中循环播放,则无法获得屏幕更新。如果您希望在10ms内发生某些事情,请将延迟的消息发布到Handler并更新该线程中的UI。

备注:永远不要在UI线程上睡觉。原因是,如果您没有将控制权返回给Looper,则无法处理输入或绘图命令。所以你的应用程序变得没有响应。如果你做了足够长的时间,它甚至可能会导致框架杀死你的应用程序无法响应。

1

更好的方法是使用Android动画。我偷了这个代码here

int colorFrom = getResources().getColor(R.color.red); 
int colorTo = getResources().getColor(R.color.blue); 
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo); 
colorAnimation.setDuration(250); // milliseconds 
colorAnimation.addUpdateListener(new AnimatorUpdateListener() { 

    @Override 
    public void onAnimationUpdate(ValueAnimator animator) { 
     textView.setBackgroundColor((int) animator.getAnimatedValue()); 
    } 

}); 
colorAnimation.start(); 
0

尝试使用runOnUiThread

public void onCreate(Bundle savedInstanceState) { 
     res = getResources(); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.xyz);//**Works**/ 
     handler.postDelayed(runnable, 10);  
    } 

    private Runnable runnable = new Runnable() { 
     public void run() { 
      runOnUiThread(new Runnable() { 
       public void run() 
       { 
        try { 
        while (number<=100) { 
          number=number+1; 
          float[] hsvColor = {0, 1, 1}; 
          hsvColor[0] = 360f * number/100; 
          color.setBackgroundColor(Color.HSVToColor(hsvColor)); 
        } 
       }catch(Exception e){ 
        //New exception 
       } 
       } 
      }); 
     } 
    }