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

就上面那個(gè),當(dāng)音樂(lè)在播放的時(shí)候,那個(gè)光碟輪子在轉(zhuǎn),就想旋轉(zhuǎn)木馬一般。感覺(jué)好好玩啊。
碰巧想起前陣子做音樂(lè)播放器,哎,那這個(gè)也可以做在手機(jī)的音樂(lè)播放器上,這樣就代替了進(jìn)度條了。
一想到,就興奮,于是,首先畫圓形,然后放置背景圖片,然后使用動(dòng)畫旋轉(zhuǎn)。當(dāng)音樂(lè)播放時(shí),同時(shí)
開(kāi)始播放圓形圖片的動(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 {// 沒(méi)有邊框
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)文章
Android自定義ViewPagerIndicator實(shí)現(xiàn)炫酷導(dǎo)航欄指示器(ViewPager+Fragment)
這篇文章主要為大家詳細(xì)介紹了Android自定義ViewPagerIndicator實(shí)現(xiàn)炫酷導(dǎo)航欄指示器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
Android開(kāi)發(fā)之RadioGroup的簡(jiǎn)單使用與監(jiān)聽(tīng)示例
這篇文章主要介紹了Android開(kāi)發(fā)之RadioGroup的簡(jiǎn)單使用與監(jiān)聽(tīng),結(jié)合實(shí)例形式分析了Android針對(duì)RadioGroup單選按鈕簡(jiǎn)單實(shí)用技巧,需要的朋友可以參考下2017-07-07
Android 監(jiān)聽(tīng)WiFi的開(kāi)關(guān)狀態(tài)實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 監(jiān)聽(tīng)WiFi的開(kāi)關(guān)狀態(tài)實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05
android 限制某個(gè)操作每天只能操作指定的次數(shù)(示例代碼詳解)
這篇文章主要介紹了android 限制某個(gè)操作每天只能操作指定的次數(shù),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
Android實(shí)現(xiàn)常見(jiàn)的驗(yàn)證碼輸入框?qū)嵗a
我們?cè)陂_(kāi)發(fā)APP的時(shí)候經(jīng)常要遇到輸入框,下面這篇文章主要給大家介紹了關(guān)于利用Android如何實(shí)現(xiàn)常見(jiàn)的驗(yàn)證碼輸入框的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09
Android 高仿微信語(yǔ)音聊天頁(yè)面高斯模糊(毛玻璃效果)
大家在使用微信聊天的時(shí)候有沒(méi)有注意到微信語(yǔ)言聊天用的是高斯模糊效果,基于代碼是如何實(shí)現(xiàn)的呢?下面小編給大家?guī)?lái)了Android 高仿微信語(yǔ)音聊天頁(yè)面高斯模糊(毛玻璃效果),感興趣的朋友一起看下吧2016-08-08
Android之軟鍵盤自動(dòng)彈出和關(guān)閉【代碼分享】
本文主要介紹了Android中軟鍵盤自動(dòng)彈出和關(guān)閉的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04
Android基于OkHttpUtils網(wǎng)絡(luò)請(qǐng)求的二次封裝
這篇文章主要介紹了Android基于OkHttpUtils網(wǎng)絡(luò)請(qǐng)求的二次封裝,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android中給fragment寫入?yún)?shù)的輕量開(kāi)發(fā)包FragmentArgs簡(jiǎn)介
這篇文章主要介紹了Android中給fragment寫入?yún)?shù)的輕量開(kāi)發(fā)包FragmentArgs簡(jiǎn)介,需要的朋友可以參考下2014-10-10

