前言
日常Android開發中,有很大一部分需要使用到漸變色,有時候UI會給我們提供一套對應的圖檔資源,這樣我們直接使用就可以了,當然我們也可以自己通過代碼實作顔色漸變:
一、XML實作顔色漸變
比較簡單的一種方式實作顔色漸變,我們通過定制一個對應的shape檔案,配置其屬性之後,直接作為android:background指派給對應的View即可。
1.建立XML檔案
在你的drawable檔案夾下建立shape資源:
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.運作檢視結果
如下圖,紅色邊框範圍内标記的就是漸變色的區域。
二、代碼實作顔色漸變
上面的方式其實已經可以應付80%以上的顔色漸變了,但是我們有時想要實作更複雜一些的顔色漸變,比如:
1.多重漸變(color1 -> color2 -> … ->colorN )
2.自定義View中繪制
3.更多其他複雜需求
這時我們可以通過LinearGradient(線性漸變)類來自定義實作我們想要的效果,以一個小Demo抛磚引玉:
在這個demo中,我們的主界面顔色漸變為(粉 -> 灰 -> 藍)
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);
從圖中我們是不是可以了解其實就是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);
}
得到結果:
最後放上源碼傳送門: