Android microphone custom View with dynamic display of Audio Tape Volume

Source: Internet
Author: User

Android microphone custom View with dynamic display of Audio Tape Volume

1. The so-called no picture, no truth, first. What we need to achieve is the button of the middle recording, and the surrounding area will display a waveform of the volume size.

2. VolumCircleBar inherits from View and we have customized it. The Code is as follows:

<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHByZSBjbGFzcz0 = "brush: java;"> 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. attribute Set; import android. view. view; import com. panshi. xuexiao. r;/*** microphone volume round button * @ author hiphonezhu@gmail.com * @ version [CCEnglish, 2014-7-25] */public class VolumCircleBar extends View {private double volumRate; // volume percentage private boolean isRecording; // recording mark private Object lock = new Object (); private Thread uiThread; private Paint mPaint; private RectF arcRect; private Matrix matrix = new Matrix (); pr Ivate final int VOLUM_INDICATE_LENGTH = 5; // volume size line length private final int CIRCLE_INNER_DISTANCE_TO_OUTSIDE = 5; // The distance from the incircle to the 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, defStyle); TypedArray typed Array = 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; // private int totalBlockCount in the middle microphone image; // number of blocks private int spliteAngle; // The angle between blocks private int circleWidth; // diameter/*** initialization */private void init (TypedArray typedArray) {for (int I = 0; I <typedArray. length (); I ++) {int attr = typedArray. getIndex (I); switch (attr) {case R. styleable. volumCircleBar_recordingColor: recordingColor = 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 (). g EtResources (), 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> 360) {throw new Ill EgalArgumentException ("spliteAngle * blockCount> 360, while the result shocould be less than 360. ") ;}// debug for test isRecording = true; volumRate = 0.5 ;}@ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {// diameter int width = MeasureSpec. getSize (widthMeasureSpec); int height = MeasureSpec. getSize (heightMeasureSpec); circleWidth = width> height? Width: height; if (arcRect = null) {arcRect = new RectF (rows, rows, circleWidth-CIRCLE_INNER_DISTANCE_TO_OUTSIDE, circleWidth-rows); // The volume display area, several pixels inside the offset // image processing matrix initBitmapMatrix ();} // forcibly set the view Size setMeasuredDimension (circleWidth, circleWidth );} /*** intermediate image compression processing */private void initBitmapMatrix () {float inn ErCircleRadius = (circleWidth-2 * (VOLUM_INDICATE_LENGTH + CIRCLE_INNER_DISTANCE_TO_OUTSIDE)/2f; // float innerRectangleWidth = (float) Math. cos (Math. PI/180) * 45) * innerCircleRadius * 2; // float translateOffset = VOLUM_INDICATE_LENGTH + Length + innerCircleRadius-innerRectangleWidth/2; // offset if (centerRes. getWidth ()> (innerRectangle Width) | centerRes. getHeight ()> (innerRectangleWidth) {// The image width or height is greater than (diameter-inner offset), and the ratio of compression if (centerRes. getWidth ()> centerRes. getHeight () {// float ratio = innerRectangleWidth/centerRes. getWidth (); matrix. postScale (ratio, ratio); float translateY = (innerRectangleWidth-(centerRes. getHeight () * ratio)/2f; // offset to ensure that the matrix is displayed in the center of the image. postTranslate (translateOffset, translateY + trans LateOffset);} else {// float ratio = innerRectangleWidth/(centerRes. getHeight () * 1.0f); matrix. postScale (ratio, ratio); float translateX = (innerRectangleWidth-(centerRes. getWidth () * ratio)/2f; // offset in the horizontal direction to ensure that the matrix is displayed in the center of the image. postTranslate (translateX + translateOffset, translateOffset);} else {// when the width and height of the image are smaller than the screen width, the float translateX = (innerRectangleWidth-centerRes is displayed in the center of the image. get Width ()/2f; float translateY = (innerRectangleWidth-centerRes. getHeight ()/2f; matrix. postTranslate (translateX + translateOffset, translateY + translateOffset);}/*** set the volume percentage * @ param rate */public void updateVolumRate (double rate) {synchronized (lock) {this. volumRate = rate; if (Thread. currentThread ()! = UiThread) {postInvalidate () ;}else {invalidate () ;}}/ *** start/stop recording */public void toggleRecord () {synchronized (lock) {isRecording =! IsRecording; if (Thread. currentThread ()! = UiThread) {postInvalidate () ;}else {invalidate () ;}}@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); canvas. drawColor (Color. TRANSPARENT); synchronized (lock) {if (isRecording) // recording in progress {// 1. draw a Green Circle mPaint. setAntiAlias (true); // eliminate the Sawtooth mPaint. setColor (recordingColor); mPaint. setStrokeWidth (1); mPaint. setStyle (Paint. style. FILL); // FILL the canvas. drawCircle (circleWidth/2f, circleWidth/2f, circleWidth/2f, mPaint); // 2. calculate the volume based on the volume percentage, number of blocks, and block interval. dynamically draw the volume size. // calculate the block angle. float blockAngle = (360 * 1.0f-spliteAngle * totalBlockCount)/totalBlockCount; int drawBlockCount = (int) (totalBlockCount * volumRate); // number of blocks drawn mPaint. setStrokeWidth (VOLUM_INDICATE_LENGTH); mPaint. setColor (stoppedColor); mPaint. setStyle (Paint. style. STROKE); // Hollow for (int I = 0; I <drawBlockCount; I ++) {canvas. drawArc (arcRect, I * (blockAngle + spliteAngle)-90, blockAngle, false, mPaint) ;}} else // stop recording {// 1. draw a gray circle mPaint. setColor (stoppedColor); mPaint. setStrokeWidth (1); mPaint. setStyle (Paint. style. FILL); // FILL the canvas. drawCircle (circleWidth/2f, circleWidth/2f, circleWidth/2f, mPaint) ;}// draw the middle microphone canvas. drawBitmap (centerRes, matrix, null );}}
There is not much time today. I can leave a message without understanding it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.