2017-02-13 186 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 
       } 
       } 
      }); 
     } 
    }