1, the so-called No picture no truth, first on. What we're going to do is the button in the middle of the recording, and the perimeter is going to show a volume-size waveform.
2, Volumcirclebar inherited from view, we made a custom, the code is as follows
Package Com.rdinfo.ccenglish.ui.ccprofile.view;import Android.content.context;import Android.content.res.typedarray;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.matrix;import Android.graphics.paint;import Android.graphics.rectf;import Android.util.attributeset;import Android.view.View; Import com.panshi.xuexiao.r;/** * Mic Volume round button * @author [email protected] * @version [Ccenglish, 2014-7-25] */public cl Volumcirclebar extends view{private double volumrate;//volume percentage private Boolean isrecording;//Recording Flag private Object lock = new Object (); Private Thread Uithread; Private Paint Mpaint; Private RECTF Arcrect; Private Matrix matrix = new Matrix (); Private final int volum_indicate_length = 5; Volume size line length private final int circle_inner_distance_to_outside = 5; Inscribed circle distance from Outer Circle public Volumcirclebar (context context) {This (context, NULL); } Public Volumcirclebar (context context, AttributeSet Attrs) {This (context, attrs, 0); } public Volumcirclebar (context context, AttributeSet attrs, int defstyle) {Super (context, Attrs, defsty Le); TypedArray TypedArray = Context.gettheme (). Obtainstyledattributes (Attrs, R.styleable.volumcirclebar, Defstyle, 0); Init (TypedArray); } private int recordingcolor; Recording background color private int stoppedcolor; Stop background color private Bitmap centerres; Middle microphone picture private int totalblockcount; Number of blocks private int spliteangle; The interval angle between blocks is the size of the private int circlewidth; Diameter/** * Initialize * * * private void init (TypedArray TypedArray) {for (int i = 0; i < Typedarray.le Ngth (); i++) {int attr = Typedarray.getindex (i); Switch (attr) {case R.styleable.volumcirclebar_recordingcolor:recordingcolo R = Typedarray.getcolor (i, color.green); Break Case R.styleable.volumcirclebar_stoppedcolor:stoppedcolor = Typedarray.getcolor (i, Color.gray); Break Case r.styleable.volumcirclebar_centerres:centerres = Bitmapfactory.decoderesource (GetContext (). getRes Ources (), Typedarray.getresourceid (i, r.drawable.ic_launcher)); Break Case R.styleable.volumcirclebar_blockcount:totalblockcount = Typedarray.getint (i, 50); Break Case R.styleable.volumcirclebar_splitangle:spliteangle = Typedarray.getint (i, 2); Break }} typedarray.recycle (); Uithread = Thread.CurrentThread (); Mpaint = new Paint (); if (Spliteangle * totalblockcount >) {throw new IllegalArgumentException ("Spliteangle * Blockcou NT >, while the result should is less than 360. "); }//debug for Test isrecording = true; Volumrate = 0.5; } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//diameter int W Idth = Measurespec.getsize (Widthmeasurespec); int height = measurespec.getsize (heightmeasurespec); Circlewidth = width > height? Width:height; if (Arcrect = = null) {Arcrect = new RECTF (Circle_inner_distance_to_outside, Circle_inner_distance_to_ou Tside, Circlewidth-circle_inner_distance_to_outside, Circlewidth-circle_inner_distance_to_outside) ; Volume display area, offset several pixels inside//Picture processing matrix Initbitmapmatrix (); }//force set View size setmeasureddimension (Circlewidth, circlewidth); }/** * Intermediate picture compression processing */private void Initbitmapmatrix () {Float Innercircleradius = (Circlewidth- 2 * (Volum_indicate_length + circle_inner_distance_to_outside))/2f; Radius of Inner Circle float innerrectanglewidth = (float) math.cos ((math.pi/180) * *) * Innercircleradius * 2; Inner circle inner tangent square side length float Translateoffset = volum_indicate_length + circle_inner_distance_to_outside + Innercircleradius -INNERRECTANGLEWIDTH/2; Offset if (Centerres.getwidth () > (innerrectanglewidth) | | centerres.getheight () > (innerrectanglewidth ) {//Picture width or height greater than (diameter-internal offset), equal compression if (Centerres.getwidth () > Centerres.getheight ()) {//By width compression float ratio = Innerrectanglewidth/centerres.getwidth (); Matrix.postscale (ratio, ratio); float Translatey = (Innerrectanglewidth-(centerres.getheight () * ratio))/2f; Offset in the ordinate direction to ensure that the picture is centered matrix.posttranslate (Translateoffset, Translatey + translateoffset); } else {//by height compression float ratio = innerrectanglewidth/(centerres.geth Eight () * 1.0f); Matrix.postscale (ratio, ratio); float TranslateX = (Innerrectanglewidth-(centerres.getwidth () * ratio))/2f; Offset in the horizontal direction to ensure that the picture is centered matrix.posttranslate (TranslateX + translateoffset, translateoffset); }} else {//when the width height of the picture is less than the width of the screen, direct the picture to the center of float TranslateX = (innerrectanglewidth -Centerres.getwidth ())/2f; float Translatey = (innerrectanglewidth-centerres.getheight ())/2f; Matrix.posttranslate (TranslateX + translateoffset, Translatey + translateoffset); }}/** * Set volume percentage * @param rate */public void updatevolumrate (double rate) {Synchroni Zed (lock) {this.volumrate = rate; if (Thread.CurrentThread ()! = Uithread) {postinvalidate (); } else {invalidate (); } } } /** * Start, stop recording * * public void Togglerecord () {synchronized (lock) {isrecording =!isrec ording; if (Thread.CurrentThread ()! = Uithread) {postinvalidate (); } else {invalidate (); }}} @Override protected void OnDraw (canvas canvas) {super.ondraw (canvas); Canvas.drawcolor (color.transparent); Synchronized (lock) {if (isrecording)//is recording {//1. Draw Green Circle MPa Int.setantialias (TRUE); Anti-aliasing Mpaint.setcolor (Recordingcolor); Mpaint.setstrokewidth (1); Mpaint.setstyle (Paint.Style.FILL); Filling canvas.drawcircle (circlewidth/2f, circlewidth/2f, circlewidth/2f, Mpaint); 2. Dynamically draw volume size based on volume percentage, block count, block interval size calculation angle//calculate block angle Float Blockangle = (* 1.0f-spliteangle * Totalblockcount)/Totalblockcount; int drawblockcount = (int) (Totalblockcount * volumrate); Number of blocks plotted mpaint.setstrokewidth (volum_indicate_length); Mpaint.setcolor (Stoppedcolor); Mpaint.setstyle (Paint.Style.STROKE); Hollow for (int i = 0; i < Drawblockcount; i++) {Canvas.drawarc (Arcrec T, I * (Blockangle + spliteangle)-Blockangle, False, Mpaint); }} else//recording stop {//1. Draw the Gray Circle Mpaint.setcolor (Stoppedcolor ); Mpaint.setstrokewidth (1); Mpaint.setstyle (Paint.Style.FILL); Filling canvas.drawcircle (circlewidth/2f, circlewidth/2f, circlewidth/2f, Mpaint); }}//Draw intermediate Microphone canvas.drawbitmap (centerres, matrix, NULL); }}
Today is not a lot of time, do not read the message you understand.