今天就跟大家聊聊有關如何在Android中自定義一個音樂波動特效圖,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。
1.自定義屬性:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="musicPlayViewAttr"> <!--指針顏色--> <attr name="point_color" format="color" /> <!--指針數量--> <attr name="point_num" format="integer" /> <!--指針寬度--> <attr name="point_width" format="float" /> <!--指針波動速度--> <attr name="point_speed" format="integer" /> </declare-styleable> </resources>
2.編寫自定義MusicPlayview
/**
* 音樂播放波動動畫
*/
public class MusicPlayView extends View {
//坐標原點x
private float mBasePointX;
//坐標原點y
private float mBasePointY;
//指針的數量 默認10
private int mPointNum;
//指針間的間隙 默認5dp
private float mPointSpace;
//每個指針的寬度 默認5dp
private float mPointWidth;
//指針的顏色
private int mPointColor = Color.RED;
//指針的集合
private List<Pointer> mPoints;
//控制開始/停止
private boolean mIsPlaying = false;
//播放線程
private Thread mPlayThread;
//指針波動速度
private int mPointSpeed;
//畫筆
private Paint mPaint;
public MusicPlayView(Context context) {
super(context);
init();
}
public MusicPlayView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
//取出自定義屬性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.musicPlayViewAttr);
mPointNum = ta.getInt(R.styleable.musicPlayViewAttr_point_num, 10);
mPointWidth = dp2px(getContext(),
ta.getFloat(R.styleable.musicPlayViewAttr_point_width, 5f));
mPointColor = ta.getColor(R.styleable.musicPlayViewAttr_point_color, Color.RED);
mPointSpeed = ta.getInt(R.styleable.musicPlayViewAttr_point_speed, 40);
init();
}
public MusicPlayView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.musicPlayViewAttr);
mPointNum = ta.getInt(R.styleable.musicPlayViewAttr_point_num, 10);
mPointWidth = dp2px(getContext(), ta.getFloat(R.styleable.musicPlayViewAttr_point_width, 5f));
mPointColor = ta.getColor(R.styleable.musicPlayViewAttr_point_color, Color.RED);
mPointSpeed = ta.getInt(R.styleable.musicPlayViewAttr_point_speed, 40);
init();
}
/**
* 初始化畫筆
*/
private void init() {
mPoints = new ArrayList<>();
//繪制虛線
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(mPointColor);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(mPointWidth);
mPaint.setPathEffect(new DashPathEffect(new float[]{25, 15}, 0));//虛線間隔
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
/**
* 設置指針高度和即那個
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//獲取邏輯原點的Y
mBasePointY = getHeight() - getPaddingBottom();
Random random = new Random();
if (mPoints != null)
mPoints.clear();
for (int i = 0; i < mPointNum; i++) {
//隨機高度
mPoints.add(new Pointer((float) (0.1 * (random.nextInt(10) + 1) * (getHeight() - getPaddingBottom() - getPaddingTop()))));
}
//計算每個指針之間的間隔 view寬度 - 左右的padding - 所有指針總共寬度 再除以多少個間隔
mPointSpace = (getWidth() - getPaddingLeft() - getPaddingRight() - mPointWidth * mPointNum) / (mPointNum - 1);
}
/**
* 開始繪制虛線
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//指針x位置
mBasePointX = 0f + getPaddingLeft() + mPointWidth / 2;
//繪制每一個指針。
for (int i = 0; i < mPoints.size(); i++) {
//繪制虛線
float[] pts = {mBasePointX, getHeight(), mBasePointX, (mBasePointY - mPoints.get(i).getHeight())};//重下往上動畫
canvas.drawLines(pts, mPaint);
//更新指針x位置
mBasePointX += (mPointSpace + mPointWidth);
}
}
/**
* 開始線程 播放
*/
public void start() {
setVisibility(VISIBLE);
if (!mIsPlaying) {
if (mPlayThread == null) {
mPlayThread = new Thread(new PlayRunnable());
mPlayThread.start();
}
mIsPlaying = true;//控制子線程中的循環
}
}
/**
* 停止線程 停止播放
*/
public void stop() {
setVisibility(INVISIBLE);
mIsPlaying = false;
invalidate();
}
/**
* 更新UI
*/
private Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
invalidate();
}
};
/**
* 子線程,循環改變每個指針的高度
*/
public class PlayRunnable implements Runnable {
@Override
public void run() {
for (float i = 0; i < Integer.MAX_VALUE; ) {
try {
for (int j = 0; j < mPoints.size(); j++) {
float rate = (float) Math.abs(Math.sin(i + j));//隨機數
mPoints.get(j).setHeight((mBasePointY - getPaddingTop()) * rate); //每個指針的高度
}
Thread.sleep(mPointSpeed);//控制動畫速度
//開始/暫停
if (mIsPlaying) {
myHandler.sendEmptyMessage(0);
i += 0.1;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 指針對象
*/
public class Pointer {
private float height;
public Pointer(float height) {
this.height = height;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
}
/**
* dp轉px
*/
public static int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources()
.getDisplayMetrics());
}
}3.在activity_main2布局中使用MusicPlayView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <com.hk.testapplication.MusicPlayView android:id="@+id/music_play" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:visibility="invisible" android:padding="10dp" app:point_color="#F44336" app:point_num="10" app:point_width="14" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/bt_play" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="播放"/> <Button android:id="@+id/bt_stop" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="停止"/> </LinearLayout> </LinearLayout>
4.MainActivity中使用
public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {
private Button mBtPlay,mBtStop;
private MusicPlayView mMusicPlayView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mMusicPlayView = findViewById(R.id.music_play);
mBtPlay = findViewById(R.id.bt_play);
mBtStop = findViewById(R.id.bt_stop);
mBtPlay.setOnClickListener(this);
mBtStop.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt_play:
//開始播放
mMusicPlayView.start();
break;
case R.id.bt_stop:
//停止播放
mMusicPlayView.stop();
break;
}
}
}看完上述內容,你們對如何在Android中自定義一個音樂波動特效圖有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。