Android 實(shí)現(xiàn)旋轉(zhuǎn)木馬的音樂(lè)效果
一、百度在線音樂(lè)旋轉(zhuǎn)木馬效果

就上面那個(gè),當(dāng)音樂(lè)在播放的時(shí)候,那個(gè)光碟輪子在轉(zhuǎn),就想旋轉(zhuǎn)木馬一般。感覺好好玩啊。
碰巧想起前陣子做音樂(lè)播放器,哎,那這個(gè)也可以做在手機(jī)的音樂(lè)播放器上,這樣就代替了進(jìn)度條了。
一想到,就興奮,于是,首先畫圓形,然后放置背景圖片,然后使用動(dòng)畫旋轉(zhuǎn)。當(dāng)音樂(lè)播放時(shí),同時(shí)
開始播放圓形圖片的動(dòng)畫,當(dāng)音樂(lè)暫停時(shí),暫停旋轉(zhuǎn);當(dāng)音樂(lè)停止播放時(shí),就停止動(dòng)畫,圖片回到原點(diǎn)。
二、效果

三、實(shí)現(xiàn)代碼
(1)MainActivity
<span style="font-size:18px;">public class MainActivity extends Activity {
MediaPlayer m1;
ImageView infoOperatingIV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoOperatingIV = (ImageView) findViewById(R.id.infoOperating);
Button play = (Button) findViewById(R.id.play);
Button stop = (Button) findViewById(R.id.stop);
play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
playMusic();
}
});
stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stopMusic();
}
});
}
private void playMusic() {
m1 = MediaPlayer.create(this, R.raw.quiet);
m1.start();
Animation operatingAnim = AnimationUtils.loadAnimation(this, R.anim.tip);
LinearInterpolator lin = new LinearInterpolator();
operatingAnim.setInterpolator(lin);
if (operatingAnim != null) {
infoOperatingIV.startAnimation(operatingAnim);
}
m1.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
infoOperatingIV.clearAnimation();
}
});
}
private void stopMusic() {
m1.stop();
infoOperatingIV.clearAnimation();
}
}</span><span style="font-size: 16pt;">
</span>
(2)畫圓的控件,這部分代碼參考了網(wǎng)友的。
<span style="font-size:18px;">public class RoundImageView extends ImageView {
private int mBorderThickness = 0;
private Context mContext;
private int defaultColor = 0xFFFFFFFF;
// 如果只有其中一個(gè)有值,則只畫一個(gè)圓形邊框
private int mBorderOutsideColor = 0;
private int mBorderInsideColor = 0;
// 控件默認(rèn)長(zhǎng)、寬
private int defaultWidth = 0;
private int defaultHeight = 0;
public RoundImageView(Context context) {
super(context);
mContext = context;
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setCustomAttributes(attrs);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
setCustomAttributes(attrs);
}
private void setCustomAttributes(AttributeSet attrs) {
TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.roundedimageview);
mBorderThickness = a.getDimensionPixelSize(R.styleable.roundedimageview_border_thickness, 0);
mBorderOutsideColor = a.getColor(R.styleable.roundedimageview_border_outside_color, defaultColor);
mBorderInsideColor = a.getColor(R.styleable.roundedimageview_border_inside_color, defaultColor);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
this.measure(0, 0);
if (drawable.getClass() == NinePatchDrawable.class)
return;
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
if (defaultWidth == 0) {
defaultWidth = getWidth();
}
if (defaultHeight == 0) {
defaultHeight = getHeight();
}
// 保證重新讀取圖片后不會(huì)因?yàn)閳D片大小而改變控件寬、高的大?。ㄡ槍?duì)寬、高為wrap_content布局的imageview,但會(huì)導(dǎo)致margin無(wú)效)
// if (defaultWidth != 0 && defaultHeight != 0) {
// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
// defaultWidth, defaultHeight);
// setLayoutParams(params);
// }
int radius = 0;
if (mBorderInsideColor != defaultColor && mBorderOutsideColor != defaultColor) {// 定義畫兩個(gè)邊框,分別為外圓邊框和內(nèi)圓邊框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - 2 * mBorderThickness;
// 畫內(nèi)圓
drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderInsideColor);
// 畫外圓
drawCircleBorder(canvas, radius + mBorderThickness + mBorderThickness / 2, mBorderOutsideColor);
} else if (mBorderInsideColor != defaultColor && mBorderOutsideColor == defaultColor) {// 定義畫一個(gè)邊框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - mBorderThickness;
drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderInsideColor);
} else if (mBorderInsideColor == defaultColor && mBorderOutsideColor != defaultColor) {// 定義畫一個(gè)邊框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - mBorderThickness;
drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderOutsideColor);
} else {// 沒有邊框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2;
}
Bitmap roundBitmap = getCroppedRoundBitmap(bitmap, radius);
canvas.drawBitmap(roundBitmap, defaultWidth / 2 - radius, defaultHeight / 2 - radius, null);
}
/**
* 獲取裁剪后的圓形圖片
*
* @param radius
* 半徑
*/
public Bitmap getCroppedRoundBitmap(Bitmap bmp, int radius) {
Bitmap scaledSrcBmp;
int diameter = radius * 2;
// 為了防止寬高不相等,造成圓形圖片變形,因此截取長(zhǎng)方形中處于中間位置最大的正方形圖片
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
int squareWidth = 0, squareHeight = 0;
int x = 0, y = 0;
Bitmap squareBitmap;
if (bmpHeight > bmpWidth) {// 高大于寬
squareWidth = squareHeight = bmpWidth;
x = 0;
y = (bmpHeight - bmpWidth) / 2;
// 截取正方形圖片
squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
} else if (bmpHeight < bmpWidth) {// 寬大于高
squareWidth = squareHeight = bmpHeight;
x = (bmpWidth - bmpHeight) / 2;
y = 0;
squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
} else {
squareBitmap = bmp;
}
if (squareBitmap.getWidth() != diameter || squareBitmap.getHeight() != diameter) {
scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap, diameter, diameter, true);
} else {
scaledSrcBmp = squareBitmap;
}
Bitmap output = Bitmap.createBitmap(scaledSrcBmp.getWidth(), scaledSrcBmp.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
Rect rect = new Rect(0, 0, scaledSrcBmp.getWidth(), scaledSrcBmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(scaledSrcBmp.getWidth() / 2, scaledSrcBmp.getHeight() / 2, scaledSrcBmp.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(scaledSrcBmp, rect, rect, paint);
bmp = null;
squareBitmap = null;
scaledSrcBmp = null;
return output;
}
/**
* 邊緣畫圓
*/
private void drawCircleBorder(Canvas canvas, int radius, int color) {
Paint paint = new Paint();
/* 去鋸齒 */
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint.setColor(color);
/* 設(shè)置paint的 style 為STROKE:空心 */
paint.setStyle(Paint.Style.STROKE);
/* 設(shè)置paint的外框?qū)挾?*/
paint.setStrokeWidth(mBorderThickness);
canvas.drawCircle(defaultWidth / 2, defaultHeight / 2, radius, paint);
}
}</span><span style="font-size: 16pt;">
</span>
以上就是Android 實(shí)現(xiàn)旋轉(zhuǎn)木馬的音樂(lè)效果,有需要的朋友可以參考下。
相關(guān)文章
Kotlin創(chuàng)建一個(gè)好用的協(xié)程作用域
這篇文章主要介紹了Kotlin創(chuàng)建一個(gè)好用的協(xié)程作用域,kotlin中使用協(xié)程,是一定要跟協(xié)程作用域一起配合使用的,否則可能協(xié)程的生命周期無(wú)法被準(zhǔn)確控制,造成內(nèi)存泄漏或其他問(wèn)題2022-07-07
解析Android點(diǎn)擊事件分發(fā)機(jī)制
本篇文章主要介紹了解析Android點(diǎn)擊事件分發(fā)機(jī)制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Flutter使用AnimatedSwitcher實(shí)現(xiàn)場(chǎng)景切換動(dòng)畫
在應(yīng)用中,我們經(jīng)常會(huì)遇到切換組件的場(chǎng)景。本文將利用Flutter中提供的AnimatedSwitcher這一動(dòng)畫組件來(lái)實(shí)現(xiàn)頁(yè)面內(nèi)的場(chǎng)景切換,需要的可參考一下2022-03-03
Android取消EditText自動(dòng)獲取默認(rèn)焦點(diǎn)
本文主要介紹了Android取消EditText自動(dòng)獲取焦點(diǎn)默認(rèn)行為的方法,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03
android 之Spinner下拉菜單實(shí)現(xiàn)級(jí)聯(lián)
android 之Spinner下拉菜單實(shí)現(xiàn)級(jí)聯(lián),需要的朋友可以參考一下2013-02-02
Android實(shí)現(xiàn)TextView字符串關(guān)鍵字變色的方法
這篇文章顯示給大家介紹了字符串中關(guān)鍵字變色的實(shí)現(xiàn)方法,而后又拓展介紹了在Android中如何實(shí)現(xiàn)搜索關(guān)鍵字變色,相信對(duì)各位Android開發(fā)者們具有一定的參考借鑒價(jià)值,感興趣的朋友們下面來(lái)一起看看吧。2016-10-10

