GradientDrawable

用GradientDrawable实现渐变可以通过xml或者代码实现,xml实现需要在drawable下建立xml文件,在标签下建立标签。

例如gradlient_background.xml文件如下:

[代码]xml代码:1

2

3

4

5

6

7

8

设置方法如下:

[代码]xml代码:1

2

3

上面的例子中我们在gradient标签中设置了startColor,endColor,angle用来表示开始结束的颜色和变化方向。 gradient标签的所有属性说明如下:

android:angle:(Integer) 渐变的角度,线性渐变时才有效,必须是45的倍数,0表示从左到右,90表示从下到上

android:centerX:(Float)渐变中心的相对X坐标,放射渐变时才有效,在0.0到1.0之间,默认为0.5,表示在正中间

android:centerY:(Float)渐变中心的相对X坐标,放射渐变时才有效,在0.0到1.0之间,默认为0.5,表示在正中间

android:centerColor :(Color)中间点的色值

android:endColor : (Color)结束的色值

android:startColor:(Color)开始的色值。

android:gradientRadius:(Float)渐变的半径,只有在android:type=”radial”的时候有效。

android:type :有三种类型 “linear” 线性渐变, “radial” 放射渐变,设置该项时,android:gradientRadius也必须设置 “sweep” 扫描性渐变

android:useLevel : 如果为true,将被当成LevelListDrawable使用。

除了用xml设置,还可以在编码中设置,标签对应的类是GradientDrawable,GradientDrawable是Drawable的子类。 代码如下:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49public class TestActivity   extends Activity   {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(new SampleView(this));

}

private static class SampleView   extends View {

private Rect mRect;

private GradientDrawable mDrawable;

public SampleView(Context context) {

super(context);

setFocusable(true);

mRect   = new Rect(0,   0, 300, 300);

mDrawable   = new GradientDrawable(GradientDrawable.Orientation.TL_BR,

new int[] { 0xaa000000,

0xFFFFFFFF });

mDrawable.setShape(GradientDrawable.RECTANGLE);

mDrawable.setGradientRadius((float)(Math.sqrt(2)   * 60));

}

static void setCornerRadii(GradientDrawable drawable, float r0,

float r1, float r2, float r3) {

drawable.setCornerRadii(new float[] { r0, r0, r1, r1,

r2,   r2, r3, r3 });

}

@Override protected void onDraw(Canvas   canvas) {

mDrawable.setBounds(mRect);

float r = 16;

canvas.save();

canvas.translate(10,   10);

mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);

setCornerRadii(mDrawable,   r, r, 0, 0);

mDrawable.draw(canvas);

canvas.restore();

canvas.save();

canvas.translate(10 + mRect.width() + 10, 10);

mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);

setCornerRadii(mDrawable,   0, 0, r, r);

mDrawable.draw(canvas);

canvas.restore();

canvas.translate(0,   mRect.height() + 10);

canvas.save();

canvas.translate(10,   10);

mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);

setCornerRadii(mDrawable,   0, r, r, 0);

mDrawable.draw(canvas);

canvas.restore();

}

}

}

可以看到,代码设置和xml设置大同小异,注意实例化的操作:

[代码]java代码:1

2

3public GradientDrawable(Orientation orientation, int[] colors) {

this(new GradientState(orientation, colors));

}

第一个参数是一个枚举,表示渐变方向,这个用来相当于xml里面的angle,只不过angle是用45的倍数表示方向,而枚举看上去更清楚了。

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18public enum Orientation   {

/**   draw the gradient from the top to the bottom */

TOP_BOTTOM,

/**   draw the gradient from the top-right to the bottom-left */

TR_BL,

/**   draw the gradient from the right to the left */

RIGHT_LEFT,

/**   draw the gradient from the bottom-right to the top-left */

BR_TL,

/**   draw the gradient from the bottom to the top */

BOTTOM_TOP,

/**   draw the gradient from the bottom-left to the top-right */

BL_TR,

/**   draw the gradient from the left to the right */

LEFT_RIGHT,

/**   draw the gradient from the top-left to the bottom-right */

TL_BR,

}

第二个参数是一个color数组,相当于startColor,endColor,centerColor,其中centerColor可以省略,但是至少要设置两个颜色。 mDrawable.setGradientType可以设置三种type同xml一样,分别是GradientDrawable.LINEAR_GRADIENT,GradientDrawable .RADIAL_GRADIENT,GradientDrawable.SWEEP_GRADIENT。

Shader类的子类

Shader类的子类创建允许使用多种固体颜色填充绘图对象的Paint,功能不只是实现渐变填充。有三Shader是用来做渐变的: LinearGradient、RadialGradient和 SweepGradient. 看名字就知道这三种和上面的GradientDrawable的三种type是对应的。 只不过是用Shader实现了。

要在绘图的时候使用一个Shader,可以使用setShader方法将其应用到一个Paint中,如下面的代码所示:

[代码]java代码:1

2Paint shaderPaint = new Paint();

shaderPaint.setShader(myLinearGradient);

使用这个Paint所绘制的任何东西都将使用你指定的Shader进行填充,而不是使用Paint本身的颜色进行填充。

下面使用LinearGradient实现渐变,对于RadialGradient和 SweepGradient使用很类似。

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43public class TestActivity   extends Activity   {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(new SampleView(this));

}

private static class SampleView   extends View {

private Paint mPaint;

private Rect mRect;

LinearGradient   lg1 ;

LinearGradient   lg2 ;

LinearGradient   lg3 ;

public SampleView(Context context) {

super(context);

setFocusable(true);

mPaint   = new Paint(Paint.ANTI_ALIAS_FLAG);

mRect   = new Rect(0,   0, 300, 300);

lg1   = new LinearGradient(0,0,150,150,   Color.TRANSPARENT,Color.BLACK,

Shader.TileMode.MIRROR);

lg2   = new LinearGradient(0,0,150,150,   Color.TRANSPARENT,Color.BLACK,

Shader.TileMode.CLAMP);

lg3   = new LinearGradient(0,0,150,150,   Color.TRANSPARENT,Color.BLACK,

Shader.TileMode.REPEAT);

}

@Override protected void onDraw(Canvas   canvas) {

canvas.save();

canvas.translate(10,   10);

mPaint.setShader(lg1)   ;

canvas.drawRect(mRect,mPaint);

canvas.restore();

canvas.save();

canvas.translate(10 + mRect.width() + 10, 10);

mPaint.setShader(lg2)   ;

canvas.drawRect(mRect,mPaint);

canvas.restore();

canvas.save();

canvas.translate(10,10 + mRect.height() + 10);

mPaint.setShader(lg3)   ;

canvas.drawRect(mRect,mPaint);

canvas.restore();

}

}

}

上面的例子使用了三种Shader TileModes,如果Shader画刷所定义的区域比要填充的区域小,那么TileMode将会决定如何处理剩余的区域:

MIRROR 在水平和垂直方向上拉伸Shader图像,这样每一个图像就都能与上一个缝合了。

CLAMP 使用Shader的边界颜色来填充剩余的空间。

REPEAT 在水平和垂直方向上重复Shader图像,但不拉伸它。

LinearGradient有两种方式实例化:

[代码]java代码:1

2LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)

LinearGradient(float x0, float y0, float x1, float y1, int color0,   int color1,   Shader.TileMode tile)

他们的不同之处为参数中第一种方法可以用颜色数组,和位置来实现更细腻的过渡效果, 比如颜色采样int[] colors数组中存放20种颜色,则渐变将会逐一处理。而第二种方法参数仅为起初颜色color0和最终颜色color1。

自定义渐变

可以利用工具类重新计算LinearGradient的颜色参数,从而实现更柔和的渐变,仍然使用最开始的LinearLayout布局测试:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15public class TestActivity   extends Activity    {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_test);

if(Build.VERSION.SDK_INT   >= android.os.Build.VERSION_CODES.JELLY_BEAN) {

View   bottom = findViewById(R.id.layout_bottom);

bottom.setBackground(

ScrimUtil.makeCubicGradientScrimDrawable(

0xaa000000,   //颜色

8,   //渐变层数

Gravity.BOTTOM));   //起始方向

}

}

}

ScrimUtil代码如下:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52public class ScrimUtil   {

private ScrimUtil() {

}

/**

* Creates   an approximated cubic gradient using a multi-stop linear gradient. See

* this   post for more

* details.

*/

public static Drawable makeCubicGradientScrimDrawable(int baseColor, int numStops, int gravity) {

numStops   = Math.max(numStops, 2);

PaintDrawable   paintDrawable = new PaintDrawable();

paintDrawable.setShape(new RectShape());

final int[] stopColors = new int[numStops];

int red = Color.red(baseColor);

int green = Color.green(baseColor);

int blue = Color.blue(baseColor);

int alpha = Color.alpha(baseColor);

for (int i = 0; i < numStops; i++) {

float x = i * 1f / (numStops - 1);

float opacity = constrain(0, 1, (float)   Math.pow(x, 3));

stopColors[i]   = Color.argb((int) (alpha * opacity), red, green, blue);

}

final float x0, x1, y0, y1;

switch (gravity &   Gravity.HORIZONTAL_GRAVITY_MASK) {

case Gravity.LEFT:  x0 = 1; x1 = 0; break;

case Gravity.RIGHT: x0 = 0; x1 = 1; break;

default:              x0 = 0; x1 = 0; break;

}

switch (gravity &   Gravity.VERTICAL_GRAVITY_MASK) {

case Gravity.TOP:    y0 = 1; y1   = 0; break;

case Gravity.BOTTOM: y0 = 0; y1 = 1; break;

default:               y0 = 0; y1 = 0; break;

}

paintDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() {

@Override

public Shader resize(int width, int height) {

LinearGradient   linearGradient = new LinearGradient(

width   * x0,

height   * y0,

width   * x1,

height   * y1,

stopColors,   null,

Shader.TileMode.CLAMP);

return linearGradient;

}

});

return paintDrawable;

}

private  static float constrain(float min, float max, float v) {

return Math.max(min, Math.min(max, v));

}

}

使用属性动画实现动态渐变

使用ArgbEvaluator.evaluate(floatfraction, Object startValue, Object endValue); 可以实现颜色动态渐变,使用一个自定义view来测试:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51public class TestLayout   extends View {

public TestLayout(Context context) {

super(context);

init(null,   0);

}

public TestLayout(Context context, AttributeSet   attrs) {

super(context,   attrs);

init(attrs,   0);

}

public TestLayout(Context context, AttributeSet   attrs, int defStyle)   {

super(context,   attrs, defStyle);

init(attrs,   defStyle);

}

@SuppressWarnings("deprecation")

private void init(AttributeSet attrs, int defStyle) {

}

/**

*   =============================================================================================

* The   Animator methods

*   =============================================================================================

*/

/**

*开始背景动画(此处为属性动画)

*/

void startBackgroundAnimator(){

/*

*参数解释:

*target:设置属性动画的目标类,此处是当前自定义view所以使用this

*propertyName:属性名称。(要对View的那个属性执行动画操作)

*values数组:根据时间的推移动画将根据数组的内容进行改变

*/

ValueAnimator   anim = ObjectAnimator.ofInt(this, "backgroundColor",   Color.RED,Color.BLUE,Color.GRAY,Color.GREEN);

//动画持续时间为3秒

anim.setDuration(3000);

/*

*   ArgbEvaluator:这种评估者可以用来执行类型之间的插值整数值代表ARGB颜色。

*   FloatEvaluator:这种评估者可以用来执行浮点值之间的插值。

*   IntEvaluator:这种评估者可以用来执行类型int值之间的插值。

*   RectEvaluator:这种评估者可以用来执行类型之间的插值矩形值。

*

*由于本例是改变View的backgroundColor属性的背景颜色所以此处使用ArgbEvaluator

*/

anim.setEvaluator(new ArgbEvaluator());

//设置动画重复次数,此处设置无限重复

anim.setRepeatCount(ValueAnimator.INFINITE);

//设置重复模式

anim.setRepeatMode(ValueAnimator.REVERSE);

//开启动画

anim.start();

}

}

布局如下:

[代码]java代码:1

2

3

在activity中调用:

[代码]java代码:1

2

3

4

5

6

7

8

9public class TestActivity   extends Activity    {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_test);

TestLayout   bottom = (TestLayout) findViewById(R.id.layout_bottom);

bottom.startBackgroundAnimator()   ;

}

}

android 颜色渐变动画,Android渐变研究相关推荐

  1. android 缩放透明动画,Android旋转、平移、缩放和透明度渐变的补间动画

    android实现旋转.平移.缩放和透明度渐变的补间动画,具体实现如下: 1.在新建项目的res目录中,创建一个名为anim的目录,并在该目录中创建实现旋转.平移.缩放和透明度渐变的动画资源文件. 透 ...

  2. android标题栏渐变动画,Android 顶部标题栏随滑动时的渐变隐藏和渐变显示效果

    各位早上好,话不多说,先上效果图: 注意顶部:首页textview的变化(显示和隐藏)! 首先分析下:ui状态,其是由recyclerview添加头部组成+recyclerview 头部添加和recy ...

  3. android 颜色过渡动画效果,Android buttom textview 颜色平滑过渡的动画效果

    1.TransitionDrawable.例如,在文件夹中绘制一个xml文件,你可以这样写: 然后,在你的xml的实际检视你都引用这个TransitionDrawable在android:backgr ...

  4. android 呼吸气泡动画,Android:会呼吸的悬浮气泡

    Android:会呼吸的悬浮气泡 写在前面 最早看到这个效果是 MIUI6 系统升级界面,有很多五颜六色的气泡悬浮着,觉得很好看. 可惜现在找不到动态图了.而且虽然 MIUI8 更新界面也有类似的气泡 ...

  5. android 上下扫描动画,Android扫描雷达动画

    很简单的一个组合动画,用好基本动画啥子效果都不怕 老规矩先上图 效果图.gif ok 来 既然往下翻那就看看如何实现的吧 首先效果分为两部分 第一部分中间指针(其实这里就是一张图片) 第二部分就是波纹 ...

  6. android显示绘图动画,Android自定义View绘图实现渐隐动画

    实现了一个有趣的小东西:使用自定义view绘图,一边画线,画出的线条渐渐变淡,直到消失.效果如下图所示: 用属性动画或者渐变填充(shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边 ...

  7. android studio实现动画,android studio上的基本动画实现(第一篇)

    hello,各位小伙伴们,在不少小伙伴们刚刚开始学习android的时候,经常会有一些project里面须要有一些基本动画的插入,那么具体是要怎么实现呢?咱们接下一块儿分析一下在android中的几种 ...

  8. android编程xml动画,Android中xml设置Animation动画效果详解

    在Android中,Animation动画效果的实现可以通过两种方式进行实现,一种是tweened animation渐变动画,另一种是frame by frame animation画面转换动画. ...

  9. android 雷达搜索动画,Android实现微信雷达辐射搜索好友实例(逻辑清晰实现简单)...

    Android仿微信雷达扫描,仿安卓微信.云播雷达扫描动画效果点击中间的黑色圆圈开始扫描动画,再次点击复位,需要这种效果的朋友快点收藏了吧. 效果图如下: 这个界面大家肯定都非常熟悉了,下面来说一下原 ...

最新文章

  1. JAVA动态读取xml_Java动态生成和解析xml文件步骤详解
  2. 机器学习理论基础到底有多可靠?
  3. 净误差与遗漏为负值的含义_巴丹吉林沙漠湖泊水位变化及地下水净补给量
  4. Bigo 实时计算平台建设实践
  5. STL之set_union、set_intersection、set_difference、set_symmetric_difference
  6. 【深度学习笔记】个人阅读的Deep Learning方向的paper整理
  7. 【bzoj 3252】攻略
  8. pc端滚动去掉滚动条scroll
  9. Let 's watch TV
  10. 【CSAPP】程序的机器级表示:基础知识
  11. 用Java来解析torrent文件
  12. php程序的运行方法
  13. 助力自己在金融领域中更加游刃有余的人大与加拿大女王大学金融硕士项目你读到了吗?
  14. (翻译)缩略图(Thumbnail)
  15. 怎么上传云班课的计算机作业,云班课作业怎么提交_作业提交方法_咖绿茵手游站...
  16. 视频m4v怎么转换成mp4?
  17. 在小程序中使用iconfont
  18. python计算机视觉学习第8章——图像内容分类
  19. 基于微信小程序的同城家政服务小程序
  20. 求奇数分之一序列前N项和

热门文章

  1. 重金属废水处理如何做到达标排放的同时实现环保资源化
  2. 怎么用代码自动点击_代码详解:用Mask R-CNN赋予自动驾驶汽车“火眼金睛”
  3. CDQ分治【分治(真得头疼)
  4. 杭州AI开发者Meetup报名开启!
  5. 樱花雨html,樱花雨
  6. LiveGBS国标流媒体平台-海康NVR摄像机自带物联网卡摄像头注册GB/T28181国标平台看不到设备的时候如何抓包及排查
  7. 用Selenium(Python)代填返校报备
  8. 华为HCIP-RS 数通笔记
  9. 小时光扫地机器人圆圆_《致我们暖暖的小时光》:国产剧与韩剧之间,差了一点佐料叫“格局”...
  10. SQL SEVER连线查询数据源IP地址及开启SQL的IP地址连线方法