要用textview使用渐变色,那我们就必须要了解lineargradient(线性渐变)的用法。
lineargradient的参数解释
lineargradient也称作线性渲染,lineargradient的作用是实现某一区域内颜色的线性渐变效果,看源码你就知道他是shader的子类。
它有两个构造函数
1
2
|
public lineargradient( float x0, float y0, float x1, float y1, int color0, int color1, shader.tilemode tile) public lineargradient ( float x0, float y0, float x1, float y1, int [] colors, float [] positions, shader.tilemode tile); |
其中,参数x0表示渐变的起始点x坐标;参数y0表示渐变的起始点y坐标;参数x1表示渐变的终点x坐标;参数y1表示渐变的终点y坐标 ;color0表示渐变开始颜色;color1表示渐变结束颜色;参数tile表示平铺方式。
shader.tilemode有3种参数可供选择,分别为clamp、repeat和mirror:
clamp的作用是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色
repeat的作用是在横向和纵向上以平铺的形式重复渲染位图
mirror的作用是在横向和纵向上以镜像的方式重复渲染位图
lineargradient的简单使用
先实现文字效果的水平渐变:
1
2
|
shader shader_horizontal= new lineargradient(btwidth/ 4 , 0 , btwidth, 0 , color.red, color.green, shader.tilemode.clamp); tv_text_horizontal.getpaint().setshader(shader_horizontal); |
再实现文字的垂直渐变效果:
1
2
|
shader shader_vertical= new lineargradient( 0 , btheight/ 4 , 0 , btheight, color.red, color.green, shader.tilemode.clamp); tv_text_vertical.getpaint().setshader(shader_vertical); |
接下来来实现文字的颜色动态渐变效果:
1
2
3
4
5
6
7
8
9
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
52
53
54
55
56
57
58
59
60
61
62
63
64
|
import android.content.context; import android.graphics.canvas; import android.graphics.lineargradient; import android.graphics.matrix; import android.graphics.paint; import android.graphics.shader; import android.util.attributeset; import android.widget.textview; /** * created on 2016/3/13. */ public class gradienthorizontaltextview extends textview { private lineargradient mlineargradient; private matrix mgradientmatrix; //渐变矩阵 private paint mpaint; //画笔 private int mviewwidth = 0 ; //textview的宽 private int mtranslate = 0 ; //平移量 private boolean manimating = true ; //是否动画 private int delta = 15 ; //移动增量 public gradienthorizontaltextview(context ctx) { this (ctx, null ); } public gradienthorizontaltextview(context context, attributeset attrs) { super (context, attrs); } @override protected void onsizechanged( int w, int h, int oldw, int oldh) { super .onsizechanged(w, h, oldw, oldh); if (mviewwidth == 0 ) { mviewwidth = getmeasuredwidth(); if (mviewwidth > 0 ) { mpaint = getpaint(); string text = gettext().tostring(); int size; if (text.length()> 0 ) { size = mviewwidth* 2 /text.length(); } else { size = mviewwidth; } mlineargradient = new lineargradient(-size, 0 , 0 , 0 , new int [] { 0x33ffffff , 0xffffffff , 0x33ffffff }, new float [] { 0 , 0 .5f, 1 }, shader.tilemode.clamp); //边缘融合 mpaint.setshader(mlineargradient); //设置渐变 mgradientmatrix = new matrix(); } } } @override protected void ondraw(canvas canvas) { super .ondraw(canvas); if (manimating && mgradientmatrix != null ) { float mtextwidth = getpaint().measuretext(gettext().tostring()); //获得文字宽 mtranslate += delta; //默认向右移动 if (mtranslate > mtextwidth+ 1 || mtranslate< 1 ) { delta = -delta; //向左移动 } mgradientmatrix.settranslate(mtranslate, 0 ); mlineargradient.setlocalmatrix(mgradientmatrix); postinvalidatedelayed( 30 ); //刷新 } } } |
实现歌词进度效果
canvas 作为绘制文本时,使用fontmetrics对象,计算位置的坐标。它的思路和java.awt.fontmetrics的基本相同。
fontmetrics对象它以四个基本坐标为基准,分别为:
fontmetrics.top
fontmetrics.ascent
fontmetrics.descent
fontmetrics.bottom
1
2
3
4
5
6
7
8
9
10
|
// fontmetrics对象 fontmetrics fontmetrics = textpaint.getfontmetrics(); string text = "abcdefghijklmnopqrstu" ; // 计算每一个坐标 float basex = 0 ; float basey = 100 ; float topy = basey + fontmetrics.top; float ascenty = basey + fontmetrics.ascent; float descenty = basey + fontmetrics.descent; float bottomy = basey + fontmetrics.bottom; |
下面是具体实现代码:
1
2
3
4
5
6
7
8
9
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
import android.content.context; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.porterduff; import android.graphics.porterduffxfermode; import android.graphics.rectf; import android.util.attributeset; import android.view.view; /** * created on 2016/3/13. */ public class songtextview extends view { private int postindex; private paint mpaint; private int delta = 15 ; private float mtextheight; private float mtextwidth; private string mtext= "梦 里 面 看 我 七 十 二 变" ; private porterduffxfermode xformode; public songtextview(context ctx) { this (ctx, null ); } public songtextview(context context, attributeset attrs) { this (context, attrs, 0 ); } public songtextview(context context, attributeset attrs, int defstyleattr) { super (context, attrs, defstyleattr); init(); } public void init() { mpaint = new paint(paint.anti_alias_flag); xformode = new porterduffxfermode(porterduff.mode.src_in); mpaint.setcolor(color.cyan); mpaint.settextsize( 60 .0f); mpaint.setstyle(paint.style.fill_and_stroke); mpaint.setxfermode( null ); mpaint.settextalign(paint.align.left); //文字精确高度 paint.fontmetrics fontmetrics = mpaint.getfontmetrics(); mtextheight = fontmetrics.bottom-fontmetrics.descent-fontmetrics.ascent; mtextwidth = mpaint.measuretext(mtext); } /** *计算 控件的宽高 */ @override protected void onmeasure( int widthmeasurespec, int heightmeasurespec) { final int mwidth; final int mheight; /** * 设置宽度 */ int widthmode = measurespec.getmode(widthmeasurespec); int widthsize = measurespec.getsize(widthmeasurespec); if (widthmode == measurespec.exactly) // match_parent , accurate mwidth = widthsize; else { // 由图片决定的宽 int desirebyimg = getpaddingleft() + getpaddingright() + getmeasuredwidth(); if (widthmode == measurespec.at_most) // wrap_content mwidth = math.min(desirebyimg, widthsize); else mwidth = desirebyimg; } /*** * 设置高度 */ int heightmode = measurespec.getmode(heightmeasurespec); int heightsize = measurespec.getsize(heightmeasurespec); if (heightmode == measurespec.exactly) // match_parent , accurate mheight = heightsize; else { int desire = getpaddingtop() + getpaddingbottom() + getmeasuredheight(); if (heightmode == measurespec.at_most) // wrap_content mheight = math.min(desire, heightsize); else mheight = desire; } setmeasureddimension( mwidth, mheight); } @override protected void ondraw(canvas canvas) { super .ondraw(canvas); bitmap srcbitmap = bitmap.createbitmap(getmeasuredwidth(),getmeasuredheight(), bitmap.config.argb_8888); canvas srccanvas = new canvas(srcbitmap); srccanvas.drawtext(mtext, 0 , mtextheight, mpaint); mpaint.setxfermode(xformode); mpaint.setcolor(color.red); rectf rectf = new rectf( 0 , 0 ,postindex,getmeasuredheight()); srccanvas.drawrect(rectf, mpaint); canvas.drawbitmap(srcbitmap, 0 , 0 , null ); init(); if (postindex<mtextwidth) { postindex+= 10 ; } else { postindex= 0 ; } postinvalidatedelayed( 30 ); } } |
progressbar实现歌词播放效果
然后接下来的这种歌词播放进度效果是2张图片实现的,忘记是哪个那里看来的,压根以前也没有想过还可以这么样的实现。
只需要准备2张图即可:
1
2
3
4
5
6
7
8
|
<layer-list xmlns:android= "http://schemas.android.com/apk/res/android" > <item android:id= "@android:id/background" android:drawable= "@drawable/normal" /> <item android:id= "@android:id/progress" android:drawable= "@drawable/grandient" /> </layer-list> |
看见没就是2张图片,一张作为背景图一张作为进度图,是不是感觉很神奇,然后放入progressbar
1
2
3
4
5
6
7
8
9
10
11
12
|
<progressbar android:id= "@+id/pb1" style= "@android:style/widget.progressbar.horizontal" android:layout_width= "300dp" android:layout_height= "40dp" android:max= "100" android:maxheight= "2dp" android:minheight= "2dp" android:progress= "20" android:progressdrawable= "@drawable/m_progress_horizontal" android:secondaryprogress= "30" android:visibility= "gone" /> |
再加上代码动态改变progress就能实现进度的变化了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
progressbar pb1= (progressbar) findviewbyid(r.id.pb1); //设置滚动条可见 setprogressbarindeterminatevisibility( true ); progress=pb1.getprogress(); //获取初始进度 timer= new timer(); task= new timertask() { @override public void run() { progress+= 10 ; if (progress> 100 ){ progress= 0 ; } handler.sendemptymessage( 0 ); } }; timer.schedule(task, 1000 , 300 ); |
实现及进度的改变:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
handler handler= new handler(){ @override public void handlemessage(message msg) { super .handlemessage(msg); pb1.setprogress(progress); } }; @override protected void ondestroy() { super .ondestroy(); timer= null ; task= null ; handler.removecallbacksandmessages( null ); } |
效果也是不错的:
能力有限,感觉写一篇博客要弄好久,网速卡的一笔,就写到这了,其实项目里面也没有用到,休息2天了也写点东西,就觉得还是要学一点东西作为备用知识。
以上内容是小编给大家介绍的android实现歌词渐变色和进度的效果,希望对大家有所帮助!