一屋彪、前言#
*本文是緊接著上文(奇思妙想之實(shí)用類ArgbEvaluator)寫的所宰。
在這簡(jiǎn)單回顧下,上文主要提到了一個(gè)叫做
ArgbEvaluator
的一個(gè)類畜挥,通過他可以靈活實(shí)現(xiàn)一些漸變色效果仔粥,雖然好像很少人感興趣的樣子~QAQ
所以,本文主要呈現(xiàn)上文所實(shí)現(xiàn)的三種效果蟹但,以及一些可能需要注意到的細(xì)節(jié)以免和我一樣的小渣渣犯一樣的錯(cuò)誤將時(shí)間浪費(fèi)在這些小問題上
小葵子~上代碼躯泰!
喳哈哈,頭一次我不墨跡是不是很激動(dòng)
二华糖、代碼一:Viewpager滑動(dòng)背景漸變色效果
效果圖:
該效果是建立在
viewpager
滑動(dòng)時(shí)麦向,使得背景色漸變卵慰,于是乎鲤嫡,我們所利用的方法將是viewpager
的addOnPageChangeListener()
方法罢荡,在這里面通過ArgbEvaluator
獲取到不同位置的漸變色然后設(shè)置給所需要的控件笼才。這就只貼
具體代碼如下:
- 麻煩先實(shí)現(xiàn)viewpager虐先,以及聲明需要漸變的幾種顏色腐芍,還有就是背景色需要改變的那個(gè)控件。要不然特么搞毛線。昌腰。。
//這是我三個(gè)頁面分別用到的背景色
private int colors [] = {Color.RED,Color.BLUE,Color.GREEN};
//這個(gè)是喂一曰喂、呸一曰呸、嚼一曰嚼
private ViewPager viewPager;
//我這邊是控制外面的這個(gè)布局背景色漸變
private LinearLayout main_ll;
- 然后苇本,咱在
addOnPageChangeListener()
監(jiān)聽中的onPageScrolled()
方法中實(shí)現(xiàn)就好了。
//這是我聲明的一個(gè)結(jié)束顏色贰逾,這樣的話為了控制不管viewpager有幾頁都能不用寫死結(jié)束色
int endColor ;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//得到 顏色 估值器
ArgbEvaluator evaluator = new ArgbEvaluator();
//給布局設(shè)置初始顏色
main_ll.setBackgroundColor(colors[position]);
//計(jì)算不同頁面的結(jié)束顏色,最后一張的顏色是第一個(gè)顏色,其他的分別加一
endColor = position == colors.length-1 ? colors[0]:colors[position+1];
//根據(jù)positionOffset得到漸變色您单,因?yàn)閜ositionOffset本身為0~1之間的小數(shù)所以無需多做處理了
int evaluate =evaluator.evaluate(positionOffset,colors[position],endColor);
//最后設(shè)置漸變背景色給布局
main_ll.setBackgroundColor(evaluate);
}
Viewpager的滑動(dòng)漸變色就實(shí)現(xiàn)了~哈哈,上文也提到是借鑒的是這個(gè)博客學(xué)習(xí)的:
http://blog.csdn.net/u011200844/article/details/44458395
接著就是小渣渣我自己腦袋瞎想的一些效果啦~
三痒钝、代碼二:隨著EditText動(dòng)態(tài)變化的背景色漸變
*國(guó)際老慣例規(guī)矩菇怀,效果圖:
-
簡(jiǎn)單分析下:
效果圖很清楚的表明了就是用戶在輸入時(shí),其他控件的顏色隨著輸入長(zhǎng)度動(dòng)態(tài)的改變仁卷。
所以怎么實(shí)現(xiàn)呢冠场?根據(jù)上面所說的,還是用到
ArgbEvaluator
的evaluate()
方法寡具,只不過我們得理解起始和結(jié)束的概率拯钻。Viewpager
中的起始是當(dāng)前頁面,結(jié)束是下一個(gè)頁面亭姥。那么EditText
呢粮揉?對(duì)的,長(zhǎng)度制肮,我們很容易就可以想到井誉,長(zhǎng)度為‘0’為開始點(diǎn)(當(dāng)然也不一定是‘0’蕉扮,只是感覺0好理解),然后給定個(gè)長(zhǎng)度‘x’為結(jié)束點(diǎn)颗圣。
知道開始與結(jié)束的概率之后…
我特么就知道你已經(jīng)猜到了喳钟!
得到用戶當(dāng)前輸入后的長(zhǎng)度 / 我們限定的總長(zhǎng)度 = 輸入所占的百分比屁使。
對(duì)的,就是這個(gè)百分比奔则,它是一個(gè)小數(shù)蛮寂,和ArgbEvaluator
的evaluate()
方法中的第一個(gè)參數(shù)所匹配,我們只需要在EditText
的addTextChangedListener
監(jiān)聽中易茬,設(shè)置起始點(diǎn)和結(jié)束點(diǎn)的顏色就OK了~
好的酬蹋!完美代碼走起~Come baby~
- 老套路~聲明下需要的參數(shù)吧。
//定義了下控制顏色變化的長(zhǎng)度抽莱,我這設(shè)了100除嘹,好展示。
private String decimalPlaces = "100";
//顏色取值我這就一段的變化岸蜗,如果多段也還思路不變哈,就自己想辦法控制下吧叠蝇,哈哈璃岳,就是這么懶
private int colors[] ={Color.parseColor("#00aaee"),Color.parseColor("#00eeaa")};
//需要用到的控件,第二個(gè)是我想控制的背景色
private EditText editText;
private RelativeLayout rl;
- 然后請(qǐng)?jiān)诔跏蓟瘯r(shí)設(shè)置起始顏色
rl.setBackgroundColor(colors[0]);
- 最后,核心代碼貼起來~
@Override
public void afterTextChanged(Editable s) {
//得到它的長(zhǎng)度
int editSize = editText.getText().length();
//如果長(zhǎng)度大于最大值就不變色了
if (editSize > Integer.valueOf(decimalPlaces))return;
//得到 當(dāng)前所占百分比的漸變值
float result = (float)editSize/decimalPlaces;
//顏色估值器
ArgbEvaluator evaluator = new ArgbEvaluator();
//得到背景漸變色
int evaluate = evaluator.evaluate(result,colors[0],colors[1]);
rl.setBackgroundColor(evaluate);
}
*哈哈哈~是不是很簡(jiǎn)單悔捶!是不是so easy ~ 太特么簡(jiǎn)單铃慷,都不好意思貼出來了!我真是帥~
帥特么個(gè)大頭鬼蜕该!去你丫的帥犁柜,這么寫就出問題了!……為什么它喵的和想象中的不一樣呀堂淡,顏色并沒有漸變馋缅。
為毛呢?哎我去绢淀,邏輯問題萤悴?不對(duì)呀,邏輯上應(yīng)該沒錯(cuò)的皆的。
最后一頓打印數(shù)據(jù)發(fā)現(xiàn)覆履,float result = (float)editSize/decimalPlaces;
這里出了問題,它只有一位小數(shù)位费薄,四色五人后就沒了漸變的效果了硝全。
天啦嚕,怎么辦好呢楞抡。思索了幾種解決方法伟众,遇到了什么除不盡報(bào)錯(cuò),拼接字符串出錯(cuò)什么的拌倍,最后得到了一個(gè)方法赂鲤,就是
BigDecimal
類噪径。估計(jì)很多老鳥都在笑話我了,不過渣渣我確實(shí)之前很少接觸到這個(gè)類数初。
BigDecimal
主要用于一些精確的計(jì)算找爱。想了解的自己查資料吧,這不是本文重點(diǎn)泡孩,嗯噠车摄,不是我懶…
- 然后修改后的代碼。
@Override
public void afterTextChanged(Editable s) {
//得到它的長(zhǎng)度
int editSize = editText.getText().length();
//如果長(zhǎng)度大于最大值就不變色了
if (editSize > Integer.valueOf(decimalPlaces))return;
//得到 當(dāng)前所占百分比的漸變值
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的漸變就好啦下面就來貼貼 根據(jù)一天中的時(shí)間完成漸變吧仑鸥。握內(nèi)個(gè)草草的QAQ吮播,我感覺我可以分三篇文章寫,那樣就可以賺好多好多贊和關(guān)注了~(>﹏<)眼俊。真是蠢了蠢了蠢了……
四意狠、代碼三:根據(jù)一天中的時(shí)間完成漸變效果!
*恩疮胖,國(guó)際慣例:
咳咳…國(guó)際慣例只是國(guó)際慣例环戈,你是看不出效果的,那個(gè)澎灸,原因的話院塞,你看上一篇文章吧。
-
思路分析:
根據(jù)一天中的時(shí)間變化背景性昭,為什么會(huì)有這個(gè)想法呢拦止,主要是在想所謂的夜間模式什么的如果自動(dòng)化就完美了。即便實(shí)現(xiàn)不了糜颠,每個(gè)時(shí)間段有不同的顏色感覺也是蠻爽的嘛~
可是汹族,我們?cè)趺磳?shí)現(xiàn)呢?這邊括蝠,我們可能會(huì)想到開啟個(gè)線程鞠抑,然后,一直判斷時(shí)間做比較忌警,我就不說麻煩不麻煩吧搁拙,感覺上去性能也會(huì)差一大截。
那特么怎么搞法绵?
可能我懶箕速,我就查了下android監(jiān)聽時(shí)間的變化,嘿還真有朋譬,嗯哼盐茎,利用自帶的一個(gè)監(jiān)聽時(shí)間的廣播
現(xiàn)在時(shí)間監(jiān)聽到了,功能怎么實(shí)現(xiàn)呢徙赢?
邏輯的話和上面的EditText思路一般字柠。想想我們一天24個(gè)小時(shí)探越。
如果:
將當(dāng)前的小時(shí)/24 = 一天時(shí)間所占百分比。
將當(dāng)前分鐘/60 = 一小時(shí)所占百分比窑业。
于是钦幔,很自然的就想到了,在這么一個(gè)時(shí)間段控制變化常柄。
說走咱就走呀~
*首先咱先實(shí)現(xiàn)廣播的監(jiān)聽吧鲤氢。
- 新建一個(gè)類繼承BroadcastReceiver.實(shí)現(xiàn)里面的方法,已經(jīng)需要用到的參數(shù)西潘。
public class TimeChangeReceive extends BroadcastReceiver{
//這倆顏色純屬個(gè)人喜歡…
private int colors[] ={Color.parseColor("#00aaee"),Color.parseColor("#00eeaa")};
//需要改變背景色的view卷玉,想想我就直接丟這把
private View mView;
//無參構(gòu)造函數(shù),不寫的話配置文件會(huì)報(bào)錯(cuò)
public TimeChangeReceive() {}
//有參喷市,提供給acitivity傳遞用到的布局
public TimeChangeReceive(View view) { this.mView = view;}
//接受廣播方法
@Override
public void onReceive(Context context, Intent intent) {
//接收傳遞過來的監(jiān)聽
String action = intent.getAction();
//如果時(shí)間改變則監(jiān)聽到時(shí)間
if (Intent.ACTION_TIME_TICK.equals(action)){
……這就等下貼吧相种。
}
}
}
-
AndroidManifest.xml
清單文件配置下廣播。
<!-- 注冊(cè)一個(gè)監(jiān)聽時(shí)間的廣播接收者 -->
<receiver android:name=".myreceiver.TimeChangeReceive">
<intent-filter>
<action android:name="android.intent.action.TIME_TICK"></action>
</intent-filter>
</receiver>
-
Activity
里注冊(cè)下廣播和初始化背景色品姓,在onDestroy()
記得注銷廣播蚂子。
//這個(gè)init()方法
public void init(){
//得到 布局控件
time_rl = (RelativeLayout) findViewById(R.id.time_rl);
//顏色估值器
ArgbEvaluator evaluator = new ArgbEvaluator();
/**
*初始化背景顏色,得到當(dāng)前時(shí)間所對(duì)應(yīng)的漸變色,
*(哦缭黔,對(duì)了,這里有個(gè)timeToFloat的方法等下貼吧蒂破,就是一個(gè)處理時(shí)間)
*顏色還是那倆顏色馏谨。
*/
int bgColor =evaluator.evaluate(
TimeUtils.timeToFloat(Calendar.getInstance()),
colors[0], colors[1]);
//設(shè)置背景
time_rl.setBackgroundColor(bgColor);
//new 一個(gè) 時(shí)間改變廣播
timeChangeReceive = new TimeChangeReceive(time_rl);
//廣播過濾器
IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);
//注冊(cè)廣播
registerReceiver(timeChangeReceive,filter);
}
//別忘了注銷
@Override
protected void onDestroy() {
//取消監(jiān)聽
unregisterReceiver(timeChangeReceive);
super.onDestroy();
}
- 上面一段代碼中提到的那啥啥啥玩意來著。
TimeUtils.timeToFloat()
方法附迷。
//一個(gè) 通過將時(shí)間的分鐘 轉(zhuǎn)化為 0~1 的小數(shù)方法
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) {
//接收傳遞過來的監(jiān)聽
String action = intent.getAction();
//如果時(shí)間改變則監(jiān)聽到時(shí)間
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);
}
}
*本文終~~~##
等了半天這三個(gè)字了吧哈哈哈
尾語
路人葵:愿能幫到有需要的朋友~希望我能和大家伙們共同進(jìn)步,有想法可以多交流哈~~
喜歡就點(diǎn)個(gè)贊和關(guān)注吧~
有意見就評(píng)論里噴吧~