这篇文章主要介绍了Android实现歌词渐变色和进度的效果的相关资料,需要的朋友可以参考下
正文
Android实现歌词渐变色和进度的效果
要用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);}@overrideprotected 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();}}}@overrideprotected 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);}/***计算 控件的宽高*/@overrideprotected 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 , accuratemwidth = widthsize;else{// 由图片决定的宽int desirebyimg = getpaddingleft() + getpaddingright()+ getmeasuredwidth();if (widthmode == measurespec.at_most)// wrap_contentmwidth = math.min(desirebyimg, widthsize);elsemwidth = desirebyimg;}/**** 设置高度*/int heightmode = measurespec.getmode(heightmeasurespec);int heightsize = measurespec.getsize(heightmeasurespec);if (heightmode == measurespec.exactly)// match_parent , accuratemheight = heightsize;else{int desire = getpaddingtop() + getpaddingbottom()+ getmeasuredheight();if (heightmode == measurespec.at_most)// wrap_contentmheight = math.min(desire, heightsize);elsemheight = desire;}setmeasureddimension( mwidth, mheight);}@overrideprotected 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"><itemandroid:id="@android:id/background"android:drawable="@drawable/normal" /><itemandroid:id="@android:id/progress"android:drawable="@drawable/grandient" /></layer-list> |
看见没就是2张图片,一张作为背景图一张作为进度图,是不是感觉很神奇,然后放入progressbar
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<progressbarandroid: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() {@overridepublic 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(){@overridepublic void handlemessage(message msg) {super.handlemessage(msg);pb1.setprogress(progress);}};@overrideprotected void ondestroy() {super.ondestroy();timer=null;task=null;handler.removecallbacksandmessages(null);} |
效果也是不错的:

能力有限,感觉写一篇博客要弄好久,网速卡的一笔,就写到这了,其实项目里面也没有用到,休息2天了也写点东西,就觉得还是要学一点东西作为备用知识。
以上内容是小编给大家介绍的android实现歌词渐变色和进度的效果,希望对大家有所帮助!

发表评论