欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-25 16:57:21
要用textview使用渐变色,那我们就必须要了解lineargradient(线性渐变)的用法。 lineargradient的参数解释 lineargradient...

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

lineargradient的参数解释

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

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

它有两个构造函数

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的简单使用

先实现文字效果的水平渐变:

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实现歌词渐变色和进度的效果 

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

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实现歌词渐变色和进度的效果 

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

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实现歌词渐变色和进度的效果

// 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; 

下面是具体实现代码:

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实现歌词渐变色和进度的效果

<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

<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就能实现进度的变化了:

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

实现及进度的改变:

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实现歌词渐变色和进度的效果,希望对大家有所帮助!