Android实现歌词渐变色和进度的效果
要用textview使用渐变色,那我们就必须要了解lineargradient(线性渐变)的用法。
lineargradient的参数解释
lineargradient也称作线性渲染,lineargradient的作用是实现某一区域内颜色的线性渐变效果,看源码你就知道他是shader的子类。
它有两个构造函数
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);
再实现文字的垂直渐变效果:
shader shader_vertical=new lineargradient(0, btheight/4, 0, btheight, color.red, color.green, shader.tilemode.clamp); tv_text_vertical.getpaint().setshader(shader_vertical);
接下来来实现文字的颜色动态渐变效果:
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
// 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); } }
progressbar实现歌词播放效果
然后接下来的这种歌词播放进度效果是2张图片实现的,忘记是哪个那里看来的,压根以前也没有想过还可以这么样的实现。
只需要准备2张图即可:
<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); }
效果也是不错的:
能力有限,感觉写一篇博客要弄好久,网速卡的一笔,就写到这了,其实项目里面也没有用到,休息2天了也写点东西,就觉得还是要学一点东西作为备用知识。
以上内容是小编给大家介绍的android实现歌词渐变色和进度的效果,希望对大家有所帮助!
上一篇: 如何设计高效合理的MySQL查询语句
下一篇: 简单整理MySQL的日志操作命令