欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Android實(shí)現(xiàn)顏色漸變動(dòng)畫效果

 更新時(shí)間:2024年01月31日 10:57:35   作者:流浪漢kylin  
本文主要給大家介紹了Android實(shí)現(xiàn)顏色漸變動(dòng)畫效果,實(shí)現(xiàn)這樣的一個(gè)動(dòng)畫漸變的效果很簡(jiǎn)單,只需要兩步,第一步用GradientDrawable實(shí)現(xiàn)兩個(gè)顏色之間的漸變效果,第二步用屬性動(dòng)畫實(shí)現(xiàn)顏色變化的過程,需要的朋友可以參考下

1. 前言

今天來試一個(gè)顏色變化的效果,有個(gè)控件點(diǎn)擊后,背景的顏色就逐漸變成另一個(gè)顏色。類似這樣的一個(gè)效果

這個(gè)如果用自定義View是有一萬種方法去實(shí)現(xiàn),但是我們要考慮到希望所有控件都能做到,所以就不用自定義View的方式去實(shí)現(xiàn)這種效果,比如之前你的同事做了一個(gè)控件,你的產(chǎn)品讓你給這個(gè)控件的點(diǎn)擊事件加個(gè)酷炫的效果,大概上邊演示的效果。

2. 場(chǎng)景分析

可以先分析一下怎么去實(shí)現(xiàn)這個(gè)效果,首先,顏色的變化,是一個(gè)過程,那這個(gè)過程中,兩個(gè)顏色之間銜接,不能太生硬,比如你x位置還是顏色A,x+1的位置馬上變成顏色B,那這樣的變化就太生硬了,要做一個(gè)顏色變化的過程,我想到的就是用漸變做。

漸變又分3種類型,線性、放射、掃描,具體用哪種,根據(jù)你的需求,比如我想變化從左到右,那就用線性,如果想像水波紋一樣從右下角去變化,那就用放射,抱歉不是你想,是產(chǎn)品想[狗頭]。這里做演示就用線性來演示吧。

顏色銜接的問題是解決了,用漸變能讓顏色的變化過程看起來不會(huì)很突兀,那如何去實(shí)現(xiàn)顏色變化的過程,怎么去實(shí)現(xiàn)顏色A到顏色B的變化。顏色是這個(gè)控件的一個(gè)屬性,所以是不是就能馬上想到可以用屬性動(dòng)畫來實(shí)現(xiàn)。

3. 實(shí)現(xiàn)效果

ok,通過上面的分析,我們要做兩個(gè)技術(shù)點(diǎn),一個(gè)是漸變,一個(gè)是屬性動(dòng)畫。

(1)漸變的實(shí)現(xiàn)

首先漸變我們平時(shí)做,都是用xml去做,這里因?yàn)橐浜蠈傩詣?dòng)畫,所以我們要?jiǎng)討B(tài)去寫代碼,動(dòng)態(tài)實(shí)現(xiàn)漸變色的效果可以使用GradientDrawable

我們先寫一個(gè)demo看看效果,這里就用兩種顏色來演示,基佬紫和猛男粉

private fun setBg(){  
    val colors = intArrayOf(  
        Color.parseColor("#9932CC"),  
        Color.parseColor("#FF69B4")  
    )  
    val drawable = GradientDrawable()  
    drawable.gradientType = GradientDrawable.LINEAR_GRADIENT  
    drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT  
    drawable.colors = colors  
    tvTest?.background = drawable  
}

可以看到代碼很簡(jiǎn)單,最終實(shí)現(xiàn)的效果(我就不貼全代碼了,控件就一個(gè)TextView)

ok,我們要做的是中間漸變的那段區(qū)域從左邊屏幕外移動(dòng)到右邊的屏幕外,那就能實(shí)現(xiàn)一個(gè)顏色變化的過程,這個(gè)思路應(yīng)該能不難理解吧。

那么要怎么移動(dòng)呢,GradientDrawable我也不熟,沒關(guān)系,那就去看官方文檔嘛,能發(fā)現(xiàn)有個(gè)方法level,我們?cè)囍鴮憘€(gè)輪詢?nèi)ピ囋囘@個(gè)level的效果,官方有說這個(gè)Level的范圍是0-10000(這里開始上動(dòng)畫也行,為了方便也可以先用輪詢測(cè)效果)

var level = 0

private fun startLooper() {  
    handler.postDelayed({  
        if (level < 10000) {  
            level += 100  
            setBg()  
            startLooper()  
        }  
    }, 10)  
}

private fun setBg(){  
    val colors = intArrayOf(  
        Color.parseColor("#9932CC"),  
        Color.parseColor("#FF69B4")  
    )  
    val drawable = GradientDrawable()  
    drawable.gradientType = GradientDrawable.LINEAR_GRADIENT  
    drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT  
    drawable.useLevel = true  
    drawable.level = level  
    drawable.colors = colors  
    tvTest?.background = drawable  
}

看最后的效果

看得出這顏色變化只能變一半,沒辦法全部變完,level為0的效果就是單色的效果,最終的1000的level效果就是原始的樣子。那我嘗試把level設(shè)超過10000會(huì)怎樣,我設(shè)個(gè)10W

能看出好像是實(shí)現(xiàn)了這個(gè)效果。其實(shí)不然,首先這個(gè)最終也并沒有完全是單色(只要你把其中一個(gè)顏色換成白色就能很容易看出),其次后半段的速度和前面的不同

所以不能勉強(qiáng)用這個(gè)方法去做,那為什么要寫這個(gè)失敗的demo出來呢,因?yàn)槲矣X得用Level應(yīng)該也能有辦法實(shí)現(xiàn)這個(gè)效果的,只是我沒時(shí)間去認(rèn)真研究,就簡(jiǎn)單的使用的話是做不到,但是通過一些奇技淫巧肯定還是能做到的。

既然level實(shí)現(xiàn)不了我們想要的效果,沒關(guān)系,我們?cè)倏纯次臋n,發(fā)現(xiàn)其實(shí)setColors方法是有一個(gè)參數(shù)的,也有兩個(gè)參數(shù)的,雙參的方法中是一個(gè)offsets數(shù)組,那我感覺這個(gè)就是我要找的方法了,把代碼改一下。

var x = 0f

private fun startLooper() {  
    handler.postDelayed({  
        if (x < 1.1f) {  
            x += 0.1f  
            setBg()  
            startLooper()  
        }  
    }, 1000)  
}

private fun setBg() {  
    val colors = intArrayOf(  
        Color.parseColor("#9932CC"),  
        Color.parseColor("#FF69B4")  
    )  
    val offsets = floatArrayOf(  
        x - 0.1f,  
        x  
    )  
    val drawable = GradientDrawable()  
    drawable.gradientType = GradientDrawable.LINEAR_GRADIENT  
    drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT  
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {  
        drawable.setColors(colors, offsets)  
    }  
    // drawable.colors = colors  
    tvTest?.background = drawable  
}

看看最終的效果

有點(diǎn)意思,怎么搞得像個(gè)進(jìn)度條一樣,無所謂,總之這樣就能實(shí)現(xiàn)顏色漸變的這個(gè)功能,實(shí)現(xiàn)第一個(gè)目標(biāo)。

(2)顏色變化過程的實(shí)現(xiàn)

讓上面的效果更加絲滑,我們使用屬性動(dòng)畫。按理來說這個(gè)過程也應(yīng)該要用屬性動(dòng)畫來實(shí)現(xiàn),這樣才符合屬性動(dòng)畫的定義。

我們寫一個(gè)動(dòng)畫

private var mValueAnimator1: ValueAnimator? = null

fun startToStopChange() {  
    if (mValueAnimator1 == null) {  
        mValueAnimator1 = ValueAnimator.ofFloat(0f, 1.1f)  
        mValueAnimator1?.addUpdateListener {  
            x = it.animatedValue as Float  
            setBg()  
        }  
    }  
    mValueAnimator1?.setDuration(1000)?.start()  
}

整體的代碼結(jié)合起來就是

var tvTest: TextView? = null  
var x = 0f  
  
private var mValueAnimator1: ValueAnimator? = null  
  
@SuppressLint("MissingInflatedId")  
override fun onCreate(savedInstanceState: Bundle?) {  
    super.onCreate(savedInstanceState)  
    setContentView(R.layout.test_main)  
  
    tvTest = findViewById(R.id.tv_test)  
    setBg()  
  
    tvTest?.setOnClickListener {  
        startToStopChange()  
    }  
}  
  
private fun setBg() {  
    val colors = intArrayOf(  
        Color.parseColor("#9932CC"),  
        Color.parseColor("#FF69B4")  
    )  
    val offsets = floatArrayOf(  
        x - 0.1f,  
        x  
    )  
    val drawable = GradientDrawable()  
    drawable.gradientType = GradientDrawable.LINEAR_GRADIENT  
    drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT  
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {  
        drawable.setColors(colors, offsets)  
    }  
    // drawable.colors = colors  
    tvTest?.background = drawable  
}  
  
fun startToStopChange() {  
    if (mValueAnimator1 == null) {  
        mValueAnimator1 = ValueAnimator.ofFloat(0f, 1.1f)  
        mValueAnimator1?.addUpdateListener {  
            x = it.animatedValue as Float  
            setBg()  
        }  
    }  
    mValueAnimator1?.setDuration(2000)?.start()  
}

加了個(gè)點(diǎn)擊事件,看看最終的效果

ok,看得出最終的效果非常的絲滑。當(dāng)然我這個(gè)是demo,所以這樣簡(jiǎn)單寫,主要是為了說明怎么實(shí)現(xiàn),但真實(shí)要運(yùn)用到項(xiàng)目中的話了,肯定還是需要在這代碼的基礎(chǔ)上做些優(yōu)化、封裝操作的。

4. 總結(jié)

簡(jiǎn)單來說,實(shí)現(xiàn)這樣的一個(gè)動(dòng)畫漸變的效果很簡(jiǎn)單,只需要兩步,第一步用GradientDrawable實(shí)現(xiàn)兩個(gè)顏色之間的漸變效果,第二步用屬性動(dòng)畫實(shí)現(xiàn)顏色變化的過程。

這其實(shí)也就是一些很簡(jiǎn)單的基礎(chǔ)知識(shí),基礎(chǔ)知識(shí)就是你的武器庫,一個(gè)復(fù)雜的效果,如果你基礎(chǔ)牢固的話,你會(huì)把這個(gè)復(fù)雜的效果去拆分成粒度更小的效果,你知道用哪些基礎(chǔ)知識(shí)能實(shí)現(xiàn)這樣的效果,這才是一個(gè)真正的開發(fā)過程,而不是說產(chǎn)品讓你實(shí)現(xiàn)一個(gè)你沒做過的效果,你第一反應(yīng)就是去搜索抄別人的代碼,第一反應(yīng)應(yīng)該是看看你的武器庫,有沒有能實(shí)現(xiàn)這個(gè)目標(biāo)的武器。我有時(shí)也會(huì)看別人的代碼,但也主要是為了看實(shí)現(xiàn)的思路。

再?gòu)?fù)雜的效果,也是由很多個(gè)很簡(jiǎn)單的原理去實(shí)現(xiàn)的。比如這里的效果如果放到recyclerView的item中,還要從recyclerView的那塊角度加點(diǎn)東西,才能兼容。

以上就是Android實(shí)現(xiàn)顏色漸變動(dòng)畫效果的詳細(xì)內(nèi)容,更多關(guān)于Android顏色漸變的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論