blob: 549c367a0569f3fb648182b25cacc24b3441fe26 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.fmradio.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
/**
* The view used to display the visualizer
*/
public final class FmVisualizerView extends View {
private final Handler mHandler = new Handler();
private Paint mPaint = new Paint();
private float mColumnPadding = 3f;
private boolean mAnimate = false;
private int mFrequency = 100;
private static final int COLUME_PADDING_COUNTS = 2;
private static final int COLUME_COUNTS = 3;
private static final float[] DEFALT_VISUALIZER_LEVEL = new float[] {
+0.4f, 1f, -0.2f
};
private float[] mPrevLevels = DEFALT_VISUALIZER_LEVEL;
/**
* Constructor method
*
* @param context The context instance
* @param attrs The attribute set for this view
* @param defStyleAttr The default style for this view
*/
public FmVisualizerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* Constructor method
*
* @param context The context instance
* @param attrs The attribute set for this view
*/
public FmVisualizerView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* Constructor method
*
* @param context The context instance
*/
public FmVisualizerView(Context context) {
super(context);
init();
}
private void init() {
mPaint.setColor(0xff607d8b);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(0.3f);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mAnimate = false;
}
/**
* Set the padding between visualizer columns
*
* @param padding The padding between visualizer columns
*/
public void setColumnPadding(int padding) {
mColumnPadding = padding;
}
/**
* Start the animation
*/
public void startAnimation() {
mAnimate = true;
}
/**
* Start the animation
*/
public void stopAnimation() {
mAnimate = false;
}
/**
* Whether currently is under animation
*
* @return The animation state
*/
public boolean isAnimated() {
return mAnimate;
}
/**
* Set the animation frequency
*
* @param freguency The specify animation frequency to set
*/
public void setAnimateFrequency(int freguency) {
mFrequency = freguency;
}
/**
* Defined to re-freash the view
*/
private final Runnable mRefreashRunnable = new Runnable() {
public void run() {
FmVisualizerView.this.invalidate();
}
};
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.drawColor(Color.TRANSPARENT);
int viewHeight = getHeight();
int viewWidth = getWidth();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
float colWidth = ((float) (viewWidth - paddingLeft - paddingRight - COLUME_PADDING_COUNTS
* mColumnPadding))
/ COLUME_COUNTS;
float colHeight = (float) (viewHeight - paddingBottom - paddingTop);
float levels[] = new float[COLUME_COUNTS];
if (!mAnimate) {
levels = DEFALT_VISUALIZER_LEVEL;
} else {
levels = generate(COLUME_COUNTS);
}
for (int i = 0; i < COLUME_COUNTS; i++) {
float left = paddingLeft + i * (mColumnPadding + colWidth);
float right = left + colWidth;
float startY = paddingTop + colHeight / 2;
startY -= colHeight / 2 * levels[i];
if (startY < paddingTop) {
startY = paddingTop;
}
float bottom = viewHeight - paddingBottom;
RectF rect = new RectF(left, startY, right, bottom);
canvas.drawRect(rect, mPaint);
}
mHandler.removeCallbacks(mRefreashRunnable);
mHandler.postDelayed(mRefreashRunnable, mFrequency);
}
/**
* Used to generate out the float array with specify array count
*
* @param count The array count
* @return A float array with specify array count
*/
private float[] generate(int count) {
if (count <= 0) {
return null;
}
int[] sign = {
-1, 1
};
float[] result = new float[count];
for (int i = 0; i < count; i++) {
while (true) {
result[i] = (float) Math.random() * 1f
* (float) sign[(int) (Math.random() * 2)];
if (Math.abs(mPrevLevels[i] - result[i]) < 0.3f & result[i] > -0.3f) {
break;
}
}
}
mPrevLevels = result;
return result;
}
}