android-關於顏色漸變


引子

顏色漸變一般兩種方式(好像是廢話額,因為凡是涉及到特效或者動畫,基本都是兩種方式··) 

一種是寫XML配置,一種是寫純代碼;下面分別就兩個種方式給出demo;

 

方式1

在drawable/目錄下創建一個文件gradient.xml,內容如下:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:angle="0" android:endColor="@android:color/holo_red_light" android:startColor="@android:color/holo_green_light" />
</shape>

然后給某個view指定background:

 <View                  android:layout_width="@dimen/shape_width"
  android:layout_height="@dimen/shape_width"
  android:background="@drawable/gradient" />

實際效果如下:

  

 

上面的gradient,我們用了3個屬性:angle角度,startColor,endColor起始和結束的顏色;

起始結束顏色好理解,這里的這個angle,其實我們還可以指定為其他值,上面指定0 ,我們得到了一個從左到右的漸變;

此外還可以指定,  

   0 是從左到右漸變;45是從左下角向右上角漸變;90是從下到上,135是從右下角到左上角;180則是從右到左;(當然也可以是 -45,-90....)

 

 

優點:簡單有效。足以應付大部分的漸變需求;
缺點: 不夠靈活,不能滿足高級需求。而且不支持任意角度(很詭異,只支持45的倍數);

 方式二

利用LinearGradient + Paint + 自定義View;

由於是純代碼實現,我就直接帖代碼了;重點看紅色文字部分;

 1 package com.example.colorstudy;
 2 
 3 import android.content.Context;
 4 import android.content.res.TypedArray;
 5 import android.graphics.Canvas;
 6 import android.graphics.Color;
 7 import android.graphics.LinearGradient;
 8 import android.graphics.Paint;
 9 import android.graphics.Shader;
10 import android.support.annotation.Nullable;
11 import android.util.AttributeSet;
12 import android.view.View;
13 
14 public class GradientDemoView extends View {
15 
16     public GradientDemoView(Context context) {
17         this(context, null);
18     }
19 
20     public GradientDemoView(Context context, @Nullable AttributeSet attrs) {
21         this(context, attrs, 0);
22     }
23 
24     public GradientDemoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
25         super(context, attrs, defStyleAttr);
26         initAttrs(context, attrs);
27     }
28 
29     private int mode;
30 
31     private void initAttrs(Context context, AttributeSet attrs) {
32         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.GradientDemoView);
33         if (null != ta) {
34             mode = ta.getInteger(R.styleable.GradientDemoView_mode, 0);
35         }
36     }
37 
38     @Override
39     protected void onDraw(Canvas canvas) {
40         super.onDraw(canvas);
41 
42         int width = getWidth();
43         int height = getHeight();
44 
45         int colorStart = Color.RED;
46         int color1 = Color.GREEN;
47         int colorEnd = Color.BLUE;
48 
49         Paint paint = new Paint();
50 
51         //重點解析這里的漸變配置
52 /**
53  * Create a shader that draws a linear gradient along a line.   創建一個沿着"一條線"繪制線性漸變的着色器?
54  *
55  * @param x0           "一條線"開始位置的X   - 這個坐標是以 左上角為原點,對哦,android里面所有的繪制都是以控件左上角為原點(0,0)
56  * @param y0           "一條線"開始位置的Y
57  * @param x1           "一條線"結束為止的X
58  * @param y1           "一條線"結束為止的Y
59  * @param colors       顏色數組,可以是3個以上
60  * @param positions    顏色分段權重:比如說,有3種顏色,紅綠藍漸變,這里的positions的值是new float[]{0, 0.75f, 1f};
61  *                     則,0到0.75這一段,是紅色漸變為綠色,0.75到1這一段是 綠色漸變為藍色;
62  * @param tile         填充模式?
63  *                     詳解:
64  *                     CLAMP : 重復最后一種顏色直到View結束(當你的起始結束的坐標並沒有覆蓋整個View,那么這種模式將會用最后一種顏色填充剩余的部分)
65  *                     REPEAT: 當你的起始結束的坐標並沒有覆蓋整個View,這種模式將會進行顏色的重新漸變;
66  *                     MIRROR: 鏡像模式繪制,當你的起始結束的坐標並沒有覆蓋整個View,剩余的部分將會盡量和已經繪制的部分顏色對稱;
67  */
68         LinearGradient backGradient = null;
69         if (mode == 0) {
70             backGradient = new LinearGradient(0, 0, 0, height / 2,
71                     new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.CLAMP);
72         } else if (mode == 1) {
73             backGradient = new LinearGradient(0, 0, 0, height / 2,
74                     new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.REPEAT);
75         } else if (mode == 2) {
76             backGradient = new LinearGradient(0, 0, 0, height / 2,
77                     new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.MIRROR);
78         }
79 
80 
81         paint.setShader(backGradient);
82         canvas.drawRect(0, 0, width, height, paint);
83 
84     }
85 
86 
87 }

其他文件:res/values/attr.xml

<resources>
    <declare-styleable name="GradientDemoView">
        <attr name="mode" format="integer" />
    </declare-styleable>
</resources>

res/values/dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="shape_width">30dp</dimen>
</resources>

使用此控件的xml:

<GridLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnCount="2"
        android:rowCount="2">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:gravity="center"
            android:orientation="horizontal">

            <com.example.colorstudy.GradientDemoView
                android:layout_width="@dimen/shape_width"
                android:layout_height="@dimen/shape_width"
                app:mode="0" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="30dp"
                android:text="CLAMP模式" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:gravity="center"
            android:orientation="horizontal">

            <com.example.colorstudy.GradientDemoView
                android:layout_width="@dimen/shape_width"
                android:layout_height="@dimen/shape_width"
                app:mode="1" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="30dp"
                android:text="REPEAT模式" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:gravity="center"
            android:orientation="horizontal">

            <com.example.colorstudy.GradientDemoView
                android:layout_width="@dimen/shape_width"
                android:layout_height="@dimen/shape_width"
                app:mode="2" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="30dp"
                android:text="MIRROR模式 " />
        </LinearLayout>
    </GridLayout>

 實際效果:

 

 

優點:幾乎能夠滿足你能想到的所有漸變需求,處理起來很靈活;漸變色可以是3個以上,每種顏色占比多少可以自己調節,漸變的模式自己指定;而且還可以順帶加上其他特效,就這一點,xml寫配置就無法比擬;

缺點:如果是較為復雜的漸變,對開發人員要求就比較高了,而且還 可能涉及到什么數學算法之類的,數學渣一臉淚有木有·····

 

ok就醬紫咯。喜歡的大佬,歡迎復制; 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM