喜欢听音乐的朋友想必都知道,有很多音乐播放软件(如:千千静听),里面都会有一个能够伴随着音乐的节奏在不断变化的频谱。由于之前我也在开发一个音乐播放器,也有在琢磨这个功能的实现,然后我就自己写了一个自定义组件,随机生成频谱,虽说是随机生成可能对不上音乐的节奏,但是播放器中有没有这个组件的差别完全是天差地别啊。下面我就将我的想法分享给大家:
老样子,先上效果图
源码地址:http://download.csdn.net/download/mario_0824/8708259
原理图:
代码中有比较详细的注解,我就不废话了,直接上代码:
package com.example.widget; import java.util.Random; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; @SuppressLint("DrawAllocation") public class AudioPragram extends View { private int width; private Paint paint; private Random random;//随机数,用于随机生成条柱的高度 private int width_Block = 20;//用于控制小模块以及条柱的宽度 private int columnCount = 15;//整个画布中,条柱的条数 private int height_Block = 10;//小方块的高度 private boolean canDraw = false;//控制是否绘图 private int width_Canvas,height_Canvas; private int point_X[] = new int[100]; private int point_Y[] = new int[100]; private int point_x[] = new int[100]; private int point_y[] = new int[100]; private Rect rect_Block[] = new Rect[100];//小方块矩形框 private Rect rect_Column[] = new Rect[100];//条柱矩形框 public AudioPragram(Context context){ super(context); } public AudioPragram(Context context,AttributeSet attrs){ super(context, attrs); } @SuppressLint("DrawAllocation") @Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){ super.onMeasure(widthMeasureSpec,heightMeasureSpec); height_Canvas=getMeasuredHeight(); width_Canvas=getMeasuredWidth(); width=width_Canvas/(columnCount+1); initPaint(); intiRectColumn(); intiRectBlock(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(canDraw){ for(int i=0;i<columnCount;i++){ intiRectBlock(); intiRectColumn(); canvas.drawRect(rect_Column[i],paint);//绘制条柱 canvas.drawRect(rect_Block[i],paint);//绘制小方块 } } } /* * 初始化画笔Paint * */ private void initPaint(){ paint = new Paint(); paint.setDither(true);//去抖动 paint.setAntiAlias(true);//抗锯齿 paint.setStyle(Style.FILL);//设置填充模式 paint.setColor(Color.WHITE);/* 设置条柱的颜色.注意,这个Demo因为有背景图片所以设置白色条柱能够看得见,当背景颜色为白色时,记得更改条柱颜色 */ } /* * 初始化所有条柱的宽、高信息 * */ private void intiRectColumn(){ random = new Random(); for(int i=0;i<columnCount;i++){ point_X[i] = width*(i+1); point_Y[i] = random.nextInt((height_Canvas-20)); rect_Column[i] = new Rect(point_X[i]-width_Block/2,height_Canvas-point_Y[i],point_X[i]+width_Block/2,height_Canvas); } } /* * 初始化所有小方块的宽、高信息 * */ private void intiRectBlock(){ for(int i=0;i<columnCount;i++){ point_x[i] = point_X[i]; //判断条柱上次高度与当前本次高度的高度值如若本次高度未达到上次高度则小方块的高度逐渐,实现下落的效果 if(point_y[i]>point_Y[i]-height_Block){ point_y[i] = point_y[i]-10; } else{ point_y[i] = point_Y[i]; } rect_Block[i] = new Rect(point_x[i]-width_Block/2,height_Canvas-point_y[i],point_x[i]+width_Block/2,height_Canvas-point_y[i]+10); } } public boolean isCanDraw() { return canDraw; } public void setCanDraw(boolean canDraw) { this.canDraw = canDraw; } }
再者只要在布局中引用这个自定义组件就行啦;