Android自定義View旋轉(zhuǎn)圓形圖片
一個自定義View,記錄一下思路和代碼以備以后使用。
思路:
1.首先要畫一個圓形圖片和一個圓形背景圖(通過自定義View);
2.自定義View基本步驟初始化屬性,測量寬高和中心點,然后繪制圖片;
3.通過handler實現(xiàn)圖片的角度旋轉(zhuǎn).然后然后就慢慢擼.
效果圖:
1、廢話不多直接上代碼
public class MusicPlayerView extends View {
private static final long ROTATE_DELAY = 5;//旋轉(zhuǎn)動作時間
private int mRotateDegrees;//旋轉(zhuǎn)的角度
private Handler mRotate;
private int mWidth;
private int mHeight;
private float mCenterX;
private float mCenterY;
private RectF rectF;
private Bitmap mBitmapCover;
private float mCoverScale;
private BitmapShader mShader;
private Paint paint;
private boolean isRotating;
private final Runnable mRunnableRotate = new Runnable() {
@Override
public void run() {
if (isRotating) {
updateCoverRotate();
mRotate.postDelayed(mRunnableRotate, ROTATE_DELAY);
}
}
};
/**
* 更新封面角度,重新繪制圖片
*/
private void updateCoverRotate() {
mRotateDegrees += 1;
mRotateDegrees = mRotateDegrees % 360;
postInvalidate();
}
/**
* 判讀是否在旋轉(zhuǎn)
* @return
*/
public boolean isRotating() {
return isRotating;
}
/**
* 開始旋轉(zhuǎn)圖片
*/
public void start(){
isRotating=true;
mRotate.removeCallbacksAndMessages(null);
mRotate.postDelayed(mRunnableRotate,ROTATE_DELAY);
postInvalidate();
}
/**
* 停止圖片旋轉(zhuǎn)
*/
public void stop(){
isRotating = false;
postInvalidate();
}
/**
* 通過本地圖片設(shè)置封面圖
*/
public void setCoverDrawable(int coverDrawable) {
Drawable drawable = getContext().getResources().getDrawable(coverDrawable);
mBitmapCover = drawableToBitmap(drawable);
createShader();
postInvalidate();
}
/**
* 網(wǎng)絡(luò)圖片加載使用Picasso圖片加載工具
*
* @param imageUrl
*/
public void setCoverURL(String imageUrl) {
Picasso.with(getContext()).load(imageUrl).into(target);
}
public MusicPlayerView(Context context) {
super(context);
init(context, null);
}
public MusicPlayerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public MusicPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/**
* 初始化View資源
*
* @param context
* @param attrs
*/
private void init(Context context, AttributeSet attrs) {
setWillNotDraw(false);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.play_view);
Drawable mDrawableCover = a.getDrawable(R.styleable.play_view_cover);
if (mDrawableCover != null) {
mBitmapCover = drawableToBitmap(mDrawableCover);
}
a.recycle();
mRotateDegrees = 0;
//通過handler更新圖片角度
mRotate = new Handler();
rectF = new RectF();
}
/**
* 測量寬高,設(shè)置中心點中心點位置,創(chuàng)建陰影
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mWidth = MeasureSpec.getSize(widthMeasureSpec);
mHeight = MeasureSpec.getSize(heightMeasureSpec);
int minSide = Math.min(mWidth, mHeight); //取寬高最小值設(shè)置圖片寬高
mWidth = minSide;
mHeight = minSide;
setMeasuredDimension(mWidth, mHeight); //重新設(shè)置寬高
//中心點位置
mCenterX = mWidth / 2f;
mCenterY = mHeight / 2f;
//設(shè)置圖片顯示位置
rectF.set(20.0f, 20.0f, mWidth - 20.0f, mHeight - 20.0f);
createShader();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mShader == null) {
return;
}
//畫封面圖片 判讀圖片的中心距離xy,算出邊角大小,然后畫圓
float radius = mCenterX <= mCenterY ? mCenterX - 75.0f : mCenterY - 75.0f;
canvas.rotate(mRotateDegrees, mCenterX, mCenterY);
canvas.drawCircle(mCenterX, mCenterY, radius, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
}
return super.onTouchEvent(event);
}
private Target target = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mBitmapCover = bitmap;
createShader();
postInvalidate();
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
private int mCoverColor = Color.YELLOW;
private void createShader() {
if (mWidth == 0) {
return;
}
if (mBitmapCover == null) { //如果封面為為創(chuàng)建默認(rèn)顏色
mBitmapCover = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mBitmapCover.eraseColor(mCoverColor);
}
mCoverScale = ((float) mWidth) / (float) mBitmapCover.getWidth();
//創(chuàng)建縮放后的bitmap
mBitmapCover = Bitmap.createScaledBitmap(mBitmapCover,
(int) (mBitmapCover.getWidth() * mCoverScale), (int) (mBitmapCover.getHeight() * mCoverScale), true);
mShader = new BitmapShader(mBitmapCover, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(mShader);
}
/**
* 將drawable轉(zhuǎn)換為位圖 為BitmapShader準(zhǔn)備
*
* @param drawable
* @return
*/
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
int width = drawable.getIntrinsicWidth();
width = width > 0 ? width : 1;
int height = drawable.getIntrinsicHeight();
height = height > 0 ? height : 1;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
2.差點忘記一個attrs屬性
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="play_view"> <attr name="cover" format="integer"/> </declare-styleable> </resources>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android裁剪圖片為圓形圖片的實現(xiàn)原理與代碼
- Android實現(xiàn)圓形圖片的兩種方式
- Android中Glide加載圓形圖片和圓角圖片實例代碼
- 詳解Android中Glide與CircleImageView加載圓形圖片的問題
- Android編程繪制圓形圖片的方法
- 分享一個Android設(shè)置圓形圖片的特別方法
- android繪制圓形圖片的兩種方式示例
- Android自定義View實現(xiàn)旋轉(zhuǎn)的圓形圖片
- Android實現(xiàn)圓形圖片或者圓角圖片
- android自定義控件ImageView實現(xiàn)圓形圖片
- Android使用自定義ImageView實現(xiàn)圓形圖片效果
- Android開發(fā)實現(xiàn)圓形圖片功能示例
相關(guān)文章
Android入門之Fragment嵌套Fragment的用法詳解
這篇文章主要為大家詳細(xì)介紹了Android中如何實現(xiàn)Fragment嵌套Fragment的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下2023-02-02
Android短信驗證碼監(jiān)聽解決onChange多次調(diào)用的方法
本篇文章主要介紹了Android短信驗證碼監(jiān)聽解決onChange多次調(diào)用的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03
不依賴于Activity的Android全局懸浮窗的實現(xiàn)
在Android應(yīng)用開發(fā)中,經(jīng)常要遇到做全局懸浮窗的效果,本文的內(nèi)容主要是如何不依賴于Activity的全局懸浮窗的實現(xiàn)及原理,有需要的可以參考。2016-07-07
詳解Retrofit2.0 公共參數(shù)(固定參數(shù))
這篇文章主要介紹了Retrofit2.0 公共參數(shù)(固定參數(shù)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04

