天天看點

android 顔色漸變擴散,Android 顔色漸變(gradient)的實作總結

前言

日常Android開發中,有很大一部分需要使用到漸變色,有時候UI會給我們提供一套對應的圖檔資源,這樣我們直接使用就可以了,當然我們也可以自己通過代碼實作顔色漸變:

一、XML實作顔色漸變

比較簡單的一種方式實作顔色漸變,我們通過定制一個對應的shape檔案,配置其屬性之後,直接作為android:background指派給對應的View即可。

1.建立XML檔案

在你的drawable檔案夾下建立shape資源:

android 顔色漸變擴散,Android 顔色漸變(gradient)的實作總結

shape_gradient.xml檔案代碼如下:

android:endColor="@color/colorPrimary"

android:startColor="@color/colorAccent" />

解釋一下各個層級的标簽:

[shape] 根标簽,聲明一個shape

[gradient] 聲明該shape的屬性-漸變色,除此外還有其他屬性如corners、stroke、size等等

[android:angle]漸變色的角度,舉例來說,0代表從上至下顔色漸變;45代表從左至右顔色漸變;90代表從下至上顔色漸變…

[android:startColor&android:endColor] 很好了解,漸變開始的顔色和漸變結束時的顔色(從什麼顔色變到什麼顔色)

2.将漸變色賦予對應的View

直接放入MainActivity的layout檔案中:

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/shape_gradient"

tools:context="com.mei_husky.gradientdemo.MainActivity">

android:layout_height="wrap_content"

android:text="Hello World!"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

3.運作檢視結果

如下圖,紅色邊框範圍内标記的就是漸變色的區域。

android 顔色漸變擴散,Android 顔色漸變(gradient)的實作總結

二、代碼實作顔色漸變

上面的方式其實已經可以應付80%以上的顔色漸變了,但是我們有時想要實作更複雜一些的顔色漸變,比如:

1.多重漸變(color1 -> color2 -> … ->colorN )

2.自定義View中繪制

3.更多其他複雜需求

這時我們可以通過LinearGradient(線性漸變)類來自定義實作我們想要的效果,以一個小Demo抛磚引玉:

在這個demo中,我們的主界面顔色漸變為(粉 -> 灰 -> 藍)

android 顔色漸變擴散,Android 顔色漸變(gradient)的實作總結

1.LinearGradient類簡介

使用方式非常簡單:

public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],

TileMode tile)

public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],

TileMode tile)

可以看到.我們想要實作它,需要确定兩個坐标,起始坐标 -> 終點坐标,以及要漸變所有顔色的集合,以及顔色中轉的點坐标(position[]),最後還有tileMode.

關于着色器的不同模式,如果有需求,可以參考這篇文章,很詳細:

2.自定義View:

public class MyView extends View {

public MyView(Context context) {

super(context);

}

public MyView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}

public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//擷取View的寬高

int width = getWidth();

int height = getHeight();

int colorStart = getResources().getColor(R.color.colorPrimary);

int color1 = Color.GRAY;

int colorEnd = getResources().getColor(R.color.colorAccent);

Paint paint = new Paint();

LinearGradient backGradient = new LinearGradient(0, 0, 0, height, new int[]{colorStart, color1 ,colorEnd}, null, Shader.TileMode.CLAMP);

paint.setShader(backGradient);

canvas.drawRect(0, 0, width, height, paint);

}

}

然後将我們的自定義View放到MainActivity的布局檔案中,就可以看到上圖的效果啦!

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.mei_husky.gradientdemo.MainActivity">

android:layout_height="match_parent" />

3、仔細分析一波

代碼應該不難了解,我們再來回顧一下LinearGradient的構造,看看是如何實作方向上的顔色漸變(本例中為由上至下)的

LinearGradient(0, 0, 0, height, new int[]{colorStart, color1 ,colorEnd}, null, Shader.TileMode.CLAMP);

android 顔色漸變擴散,Android 顔色漸變(gradient)的實作總結

從圖中我們是不是可以了解其實就是2個坐标的顔色漸變,通過x1,y1 -> x2,y2兩個坐标實作顔色的漸變方向指定!

那麼如果我們想要實作45°對角的顔色漸變呢?很簡單,是不是坐标從(0,0)到(width,height)就可以了呢?我們試一試:

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//擷取View的寬高

int width = getWidth();

int height = getHeight();

int colorStart = getResources().getColor(R.color.colorPrimary);

int color1 = Color.GRAY;

int colorEnd = getResources().getColor(R.color.colorAccent);

Paint paint = new Paint();

LinearGradient backGradient = new LinearGradient(0, 0, width, height, new int[]{colorStart, color1 ,colorEnd}, null, Shader.TileMode.CLAMP);

// LinearGradient backGradient = new LinearGradient(0, 0, 0, height, new int[]{colorStart, color1 ,colorEnd}, null, Shader.TileMode.CLAMP);

paint.setShader(backGradient);

canvas.drawRect(0, 0, width, height, paint);

}

得到結果:

android 顔色漸變擴散,Android 顔色漸變(gradient)的實作總結

最後放上源碼傳送門: