Androidはオーディオバーの効果を実現します。
オーディオバー
次の図のように今回のオーディオストリップです。
Viewの使い方をカスタマイズするだけなので、オーディオ入力を実際にモニターしないで、ランダムにいくつかの数字をシミュレートすればいいです。
上の図のような静的なオーディオストリップを実現するなら、すぐに構想を見つけることができると思います。つまり、長方形を描きます。各長方形の間に少し距離をずらしてもいいです。以下のコードで座標を計算する方法を示した。
コード
以下は今回の完全コードです。
次の図のように今回のオーディオストリップです。
Viewの使い方をカスタマイズするだけなので、オーディオ入力を実際にモニターしないで、ランダムにいくつかの数字をシミュレートすればいいです。
上の図のような静的なオーディオストリップを実現するなら、すぐに構想を見つけることができると思います。つまり、長方形を描きます。各長方形の間に少し距離をずらしてもいいです。以下のコードで座標を計算する方法を示した。
for (int i = 0; i < mRectCount; i++) {
// 、 、 ( , )
canvas.drawRect(
(float) (mRectWidth * i + offset),
currentHeight,
(float) ( mRectWidth * (i + 1)),
mRectHeight,
mRectPaint
);
}
上記のコードの中で、これらの小さな長方形を循環して作成しました。その中で、currentHeightは小さな長方形の高さであり、横座標の連続的なオフセットによって、これらの静的な小さな長方形を作り出しました。次に矩形の高さをランダムに変化させてオーディオをシミュレートします。ここではMath.random()法を利用してこれらの高さをランダムに変えて、currentHeightに値を与えます。コードは下記の通りです。
// ,
mRandom = Math.random();
currentHeight = (float) (mRectHeight * mRandom);
これで静的効果が得られますが、ダイナミック効果はどうやって実現されますか?実はとても簡単です。onDraw()の方法でinvalidate()を呼び出して、Viewにリメイクをするように通知すればいいです。しかし、ここでは毎回新しい長方形を描き終わると、Viewにリメイクを通知する必要はありません。これはリフレッシュ速度が速すぎて、かえって効果に影響します。したがって、下記のコードを使ってViewの遅延再描画ができます。コードは以下の通りです。
posInvalidateDelayed(300);
このように300 msごとにViewに再描画を通知すれば、より良い視覚効果が得られます。最後にグラデーションを追加すると、Viewをよりリアルにすることができます。コードは以下の通りです。
@Override
protected void onSizeChanged(int w,int h,int oldW,int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
//
LinearGradient mLinearGradient;
//
int mWidth;
//
mWidth = getWidth();
//
mRectHeight = getHeight();
// ( )
mRectWidth = (mWidth-offset) / mRectCount;
//
mLinearGradient = new LinearGradient(
0,
0,
mRectWidth,
mRectHeight,
topColor,
downColor,
Shader.TileMode.CLAMP
);
//
mRectPaint.setShader(mLinearGradient);
}
この例からは、カスタムビューを作成するには、基本的な効果から、徐々に機能を追加し、より複雑な効果を描画するためのステップが必要であることが分かります。どんなに複雑なカスタムViewでもゆっくりと繰り返していく機能ですので、カスタムViewがどれだけ難しいかは気にしないでください。千里の道も一歩から始まります。始めさえすれば、だんだん上手になります。コード
以下は今回の完全コードです。
package com.example.customaf;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import com.example.afanalog.R;
/**
*
* Created by shize on 2016/9/5.
*/
public class MyAF extends View {
//
private int mRectCount;
//
private Paint mRectPaint;
//
private int topColor, downColor;
//
private int mRectWidth, mRectHeight;
//
private int offset;
//
private int mSpeed;
public MyAF(Context context) {
super(context);
}
public MyAF(Context context, AttributeSet attrs) {
super(context, attrs);
setPaint(context, attrs);
}
public MyAF(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setPaint(context, attrs);
}
public void setPaint(Context context, AttributeSet attrs){
// TypedArray
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyAF);
mRectPaint = new Paint();
//
mRectPaint.setColor(ta.getColor(R.styleable.MyAF_AFTopColor,
ContextCompat.getColor(context, R.color.top_color)));
//
topColor=ta.getColor(R.styleable.MyAF_AFTopColor,
ContextCompat.getColor(context, R.color.top_color));
//
downColor=ta.getColor(R.styleable.MyAF_AFDownColor,
ContextCompat.getColor(context, R.color.down_color));
//
mRectCount=ta.getInt(R.styleable.MyAF_AFCount, 10);
// ,
mSpeed=ta.getInt(R.styleable.MyAF_AFSpeed, 300);
//
offset=ta.getInt(R.styleable.MyAF_AFOffset, 5);
// TypeArray
ta.recycle();
}
@Override
protected void onSizeChanged(int w,int h,int oldW,int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
//
LinearGradient mLinearGradient;
//
int mWidth;
//
mWidth = getWidth();
//
mRectHeight = getHeight();
// ( )
mRectWidth = (mWidth-offset) / mRectCount;
//
mLinearGradient = new LinearGradient(
0,
0,
mRectWidth,
mRectHeight,
topColor,
downColor,
Shader.TileMode.CLAMP
);
//
mRectPaint.setShader(mLinearGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
double mRandom;
float currentHeight;
for (int i = 0; i < mRectCount; i++) {
// ,
mRandom = Math.random();
currentHeight = (float) (mRectHeight * mRandom);
// 、 、 ( , )
canvas.drawRect(
(float) (mRectWidth * i + offset),
currentHeight,
(float) ( mRectWidth * (i + 1)),
mRectHeight,
mRectPaint
);
}
// view
postInvalidateDelayed(mSpeed);
}
}
レイアウトファイルの完全なコード:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.afanalog.MainActivity">
<com.example.customaf.MyAF
android:layout_width="match_parent"
android:layout_height="match_parent"
custom:AFCount="15"
custom:AFDownColor="@color/down_color"
custom:AFSpeed="300"
custom:AFTopColor="@color/top_color"
custom:AFOffset="15"
/>
</LinearLayout>
以上は小编が绍介したAndroidのオーディオストリップの効果を実现しました。皆さんの助けを期待しています。もし何か疑问があれば、メッセージをください。ここでも私たちのサイトを応援してくれてありがとうございます。