[android]so easy實現根據viewpager、edittext、時間使背景動態漸變色效果~


一、前言#

*本文是緊接著上文(奇思妙想之實用類ArgbEvaluator)寫的。

在這簡單回顧下,上文主要提到了一個叫做ArgbEvaluator的一個類,通過他可以靈活實現一些漸變色效果,雖然好像很少人感興趣的樣子~QAQ

所以,本文主要呈現上文所實現的三種效果,以及一些可能需要注意到的細節以免和我一樣的小渣渣犯一樣的錯誤將時間浪費在這些小問題上

小葵子~上代碼!

哈哈,頭一次我不墨跡是不是很激動

二、代碼一:Viewpager滑動背景漸變色效果

效果圖:

滑動變色.gif

該效果是建立在viewpager滑動時,使得背景色漸變,于是乎,我們所利用的方法將是viewpageraddOnPageChangeListener()方法,在這里面通過ArgbEvaluator獲取到不同位置的漸變色然后設置給所需要的控件。這就只貼

具體代碼如下:

  • 麻煩先實現viewpager,以及聲明需要漸變的幾種顏色,還有就是背景色需要改變的那個控件。要不然特么搞毛線。。。
//這是我三個頁面分別用到的背景色
private int colors [] = {Color.RED,Color.BLUE,Color.GREEN};
//這個是喂一曰喂、呸一曰呸、嚼一曰嚼
private ViewPager viewPager;
//我這邊是控制外面的這個布局背景色漸變
private LinearLayout main_ll;
  • 然后,咱在addOnPageChangeListener()監聽中的onPageScrolled()方法中實現就好了。
//這是我聲明的一個結束顏色,這樣的話為了控制不管viewpager有幾頁都能不用寫死結束色
 int endColor ;    

@Override            
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {                

        //得到 顏色 估值器
        ArgbEvaluator evaluator = new ArgbEvaluator();                 
        //給布局設置初始顏色
        main_ll.setBackgroundColor(colors[position]);                
        //計算不同頁面的結束顏色,最后一張的顏色是第一個顏色,其他的分別加一
        endColor = position == colors.length-1 ? colors[0]:colors[position+1];                
        //根據positionOffset得到漸變色,因為positionOffset本身為0~1之間的小數所以無需多做處理了               
        int evaluate =evaluator.evaluate(positionOffset,colors[position],endColor);               

        //最后設置漸變背景色給布局
        main_ll.setBackgroundColor(evaluate);
   
}
Viewpager的滑動漸變色就實現了~哈哈,上文也提到是借鑒的是這個博客學習的:
http://blog.csdn.net/u011200844/article/details/44458395

接著就是小渣渣我自己腦袋瞎想的一些效果啦~


三、代碼二:隨著EditText動態變化的背景色漸變

*國際老慣例規矩,效果圖:

輸入框漸變.gif

  • 簡單分析下:

效果圖很清楚的表明了就是用戶在輸入時,其他控件的顏色隨著輸入長度動態的改變。
所以怎么實現呢?

根據上面所說的,還是用到ArgbEvaluatorevaluate()方法,只不過我們得理解起始和結束的概率。 Viewpager中的起始是當前頁面,結束是下一個頁面。那么EditText呢?對的,長度,我們很容易就可以想到,長度為‘0’為開始點(當然也不一定是‘0’,只是感覺0好理解),然后給定個長度‘x’為結束點。

知道開始與結束的概率之后…

我特么就知道你已經猜到了!
得到用戶當前輸入后的長度 / 我們限定的總長度 = 輸入所占的百分比。
對的,就是這個百分比,它是一個小數,和 ArgbEvaluatorevaluate()方法中的第一個參數所匹配,我們只需要在EditTextaddTextChangedListener監聽中,設置起始點和結束點的顏色就OK了~

好的!完美代碼走起~Come baby~

  • 老套路~聲明下需要的參數吧。
//定義了下控制顏色變化的長度,我這設了100,好展示。
private String decimalPlaces = "100";
//顏色取值我這就一段的變化,如果多段也還思路不變哈,就自己想辦法控制下吧,哈哈,就是這么懶
private int colors[] ={Color.parseColor("#00aaee"),Color.parseColor("#00eeaa")};
//需要用到的控件,第二個是我想控制的背景色
private EditText editText;
private RelativeLayout rl;
  • 然后請在初始化時設置起始顏色
rl.setBackgroundColor(colors[0]);
  • 最后,核心代碼貼起來~
@Override
public void afterTextChanged(Editable s) {   
      //得到它的長度 
      int editSize = editText.getText().length();
      //如果長度大于最大值就不變色了 
      if (editSize > Integer.valueOf(decimalPlaces))return;
      //得到 當前所占百分比的漸變值
      float result = (float)editSize/decimalPlaces;

      //顏色估值器
      ArgbEvaluator evaluator = new ArgbEvaluator();
      //得到背景漸變色
      int evaluate = evaluator.evaluate(result,colors[0],colors[1]);   
      rl.setBackgroundColor(evaluate);
}
*哈哈哈~是不是很簡單!是不是so easy ~ 太特么簡單,都不好意思貼出來了!我真是帥~

帥特么個大頭鬼!去你丫的帥,這么寫就出問題了!……為什么它喵的和想象中的不一樣呀,顏色并沒有漸變。

為毛呢?哎我去,邏輯問題?不對呀,邏輯上應該沒錯的。
最后一頓打印數據發現,float result = (float)editSize/decimalPlaces;這里出了問題,它只有一位小數位,四色五人后就沒了漸變的效果了。

天啦嚕,怎么辦好呢。思索了幾種解決方法,遇到了什么除不盡報錯,拼接字符串出錯什么的,最后得到了一個方法,就是BigDecimal類。估計很多老鳥都在笑話我了,不過渣渣我確實之前很少接觸到這個類。

BigDecimal主要用于一些精確的計算。想了解的自己查資料吧,這不是本文重點,嗯噠,不是我懶…

  • 然后修改后的代碼。
@Override
public void afterTextChanged(Editable s) {   
      //得到它的長度 
      int editSize = editText.getText().length();
      //如果長度大于最大值就不變色了 
      if (editSize > Integer.valueOf(decimalPlaces))return;
      //得到 當前所占百分比的漸變值
      BigDecimal bigEs= BigDecimal.valueOf(editSize);
      BigDecimal result = bigEs.divide(new BigDecimal(decimalPlaces), 8, RoundingMode.HALF_UP);
      

      //顏色估值器
      ArgbEvaluator evaluator = new ArgbEvaluator();
      //得到背景漸變色
      int evaluate = evaluator.evaluate(result.floatValue(),colors[0],colors[1]);   
      rl.setBackgroundColor(evaluate);
}
*好的EditText的漸變就好啦下面就來貼貼 根據一天中的時間完成漸變吧。握內個草草的QAQ,我感覺我可以分三篇文章寫,那樣就可以賺好多好多贊和關注了~(>﹏<)。真是蠢了蠢了蠢了……

四、代碼三:根據一天中的時間完成漸變效果!

*恩,國際慣例:

時間漸變.gif

咳咳…國際慣例只是國際慣例,你是看不出效果的,那個,原因的話,你看上一篇文章吧。

  • 思路分析:

根據一天中的時間變化背景,為什么會有這個想法呢,主要是在想所謂的夜間模式什么的如果自動化就完美了。即便實現不了,每個時間段有不同的顏色感覺也是蠻爽的嘛~

可是,我們怎么實現呢?這邊,我們可能會想到開啟個線程,然后,一直判斷時間做比較,我就不說麻煩不麻煩吧,感覺上去性能也會差一大截。
那特么怎么搞?

可能我懶,我就查了下android監聽時間的變化,嘿還真有,嗯哼,利用自帶的一個監聽時間的廣播

現在時間監聽到了,功能怎么實現呢?

邏輯的話和上面的EditText思路一般。想想我們一天24個小時。
如果:
將當前的小時/24 = 一天時間所占百分比。
將當前分鐘/60 = 一小時所占百分比。
于是,很自然的就想到了,在這么一個時間段控制變化。

說走咱就走呀~

*首先咱先實現廣播的監聽吧。

  • 新建一個類繼承BroadcastReceiver.實現里面的方法,已經需要用到的參數。
public class TimeChangeReceive extends BroadcastReceiver{
      //這倆顏色純屬個人喜歡…
      private int colors[] ={Color.parseColor("#00aaee"),Color.parseColor("#00eeaa")};
      //需要改變背景色的view,想想我就直接丟這把
      private View mView;
    
      //無參構造函數,不寫的話配置文件會報錯
      public TimeChangeReceive() {}
      //有參,提供給acitivity傳遞用到的布局
      public TimeChangeReceive(View view) {    this.mView = view;}
 
      //接受廣播方法
      @Override
      public void onReceive(Context context, Intent intent) {
     
            //接收傳遞過來的監聽
            String action = intent.getAction();
           //如果時間改變則監聽到時間
           if (Intent.ACTION_TIME_TICK.equals(action)){
                 ……這就等下貼吧。
           }
      }
 }

  • AndroidManifest.xml清單文件配置下廣播。
<!-- 注冊一個監聽時間的廣播接收者 -->
<receiver android:name=".myreceiver.TimeChangeReceive">    
       <intent-filter>     
       <action android:name="android.intent.action.TIME_TICK"></action>
       </intent-filter>
</receiver>
  • Activity里注冊下廣播和初始化背景色,在onDestroy()記得注銷廣播。
//這個init()方法
public void init(){
      //得到 布局控件    
      time_rl = (RelativeLayout) findViewById(R.id.time_rl);    

      //顏色估值器 
      ArgbEvaluator evaluator = new ArgbEvaluator();
      /**
       *初始化背景顏色,得到當前時間所對應的漸變色,
       *(哦,對了,這里有個timeToFloat的方法等下貼吧,就是一個處理時間)  
       *顏色還是那倆顏色。
       */  
      int bgColor =evaluator.evaluate(
                                      TimeUtils.timeToFloat(Calendar.getInstance()),            
                                      colors[0], colors[1]);
      //設置背景 
      time_rl.setBackgroundColor(bgColor);    

       //new 一個 時間改變廣播
       timeChangeReceive = new TimeChangeReceive(time_rl);  
       //廣播過濾器  
       IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);            
       //注冊廣播   
       registerReceiver(timeChangeReceive,filter);
 }

    //別忘了注銷
   @Override
   protected void onDestroy() {   
       //取消監聽  
       unregisterReceiver(timeChangeReceive);  
       super.onDestroy();
    }
  • 上面一段代碼中提到的那啥啥啥玩意來著。TimeUtils.timeToFloat()方法。
//一個 通過將時間的分鐘 轉化為 0~1 的小數方法
 public static float timeToFloat(Calendar calendar){   
     //之前好像忘了說 divide是除法 
     BigDecimal time =new BigDecimal(calendar.get(Calendar.MINUTE))
                          .divide(new BigDecimal(60), 8, RoundingMode.HALF_UP); 

      return time.floatValue();
}
  • 最后歡呼聲,吶喊聲小伙伴們得掌聲響起來吧最后一段代碼!終于特么的要寫完了QAQ,回到之前的廣播的接收方法里面。
@Override
public void onReceive(Context context, Intent intent) {    
        //接收傳遞過來的監聽  
       String action = intent.getAction();    
       //如果時間改變則監聽到時間    
       if (Intent.ACTION_TIME_TICK.equals(action)){  
       //顏色估值器 
       ArgbEvaluator evaluator = new ArgbEvaluator();
             int bgColor =evaluator.evaluate(TimeUtils.timeToFloat(Calendar.getInstance()), colors[0], colors[1]);        
        mView.setBackgroundColor(bgColor); 
       }

}

*本文終~~~##

等了半天這三個字了吧哈哈哈

尾語

路人葵:愿能幫到有需要的朋友~希望我能和大家伙們共同進步,有想法可以多交流哈~~
喜歡就點個贊和關注吧~
有意見就評論里噴吧~
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容