服务器之家

服务器之家 > 正文

Android实现歌词渐变色和进度的效果

时间:2021-06-28 15:55     来源/作者:Losileeya

要用textview使用渐变色,那我们就必须要了解lineargradient(线性渐变)的用法。

lineargradient的参数解释

lineargradient也称作线性渲染,lineargradient的作用是实现某一区域内颜色的线性渐变效果,看源码你就知道他是shader的子类。

Android实现歌词渐变色和进度的效果

它有两个构造函数

?
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);

Android实现歌词渐变色和进度的效果

再实现文字的垂直渐变效果:

?
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);

Android实现歌词渐变色和进度的效果

接下来来实现文字的颜色动态渐变效果:

?
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);//刷新
}
}
}

Android实现歌词渐变色和进度的效果

实现歌词进度效果

canvas 作为绘制文本时,使用fontmetrics对象,计算位置的坐标。它的思路和java.awt.fontmetrics的基本相同。
fontmetrics对象它以四个基本坐标为基准,分别为:

fontmetrics.top
fontmetrics.ascent
fontmetrics.descent
fontmetrics.bottom

Android实现歌词渐变色和进度的效果

?
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);
}
}

Android实现歌词渐变色和进度的效果

progressbar实现歌词播放效果

然后接下来的这种歌词播放进度效果是2张图片实现的,忘记是哪个那里看来的,压根以前也没有想过还可以这么样的实现。
只需要准备2张图即可:

Android实现歌词渐变色和进度的效果
Android实现歌词渐变色和进度的效果

?
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);
}

效果也是不错的:

Android实现歌词渐变色和进度的效果

能力有限,感觉写一篇博客要弄好久,网速卡的一笔,就写到这了,其实项目里面也没有用到,休息2天了也写点东西,就觉得还是要学一点东西作为备用知识。

以上内容是小编给大家介绍的android实现歌词渐变色和进度的效果,希望对大家有所帮助!

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部