Android自定义View旋转圆形图片

2020-11-04 02:01:34 浏览数 (1)

一个自定义View,记录一下思路和代码以备以后使用。

思路:

1.首先要画一个圆形图片和一个圆形背景图(通过自定义View); 2.自定义View基本步骤初始化属性,测量宽高和中心点,然后绘制图片; 3.通过handler实现图片的角度旋转.然后然后就慢慢撸.

效果图:

1、废话不多直接上代码

代码语言:javascript复制
public class MusicPlayerView extends View {
private static final long ROTATE_DELAY = 5;//旋转动作时间
private int mRotateDegrees;//旋转的角度
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();
}
/**
* 判读是否在旋转
* @return
*/
public boolean isRotating() {
return isRotating;
}
/**
* 开始旋转图片
*/
public void start(){
isRotating=true;
mRotate.removeCallbacksAndMessages(null);
mRotate.postDelayed(mRunnableRotate,ROTATE_DELAY);
postInvalidate();
}
/**
* 停止图片旋转
*/
public void stop(){
isRotating = false;
postInvalidate();
}
/**
* 通过本地图片设置封面图
*/
public void setCoverDrawable(int coverDrawable) {
Drawable drawable = getContext().getResources().getDrawable(coverDrawable);
mBitmapCover = drawableToBitmap(drawable);
createShader();
postInvalidate();
}
/**
* 网络图片加载使用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();
}
/**
* 测量宽高,设置中心点中心点位置,创建阴影
*
* @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); //取宽高最小值设置图片宽高
mWidth = minSide;
mHeight = minSide;
setMeasuredDimension(mWidth, mHeight);  //重新设置宽高
//中心点位置
mCenterX = mWidth / 2f;
mCenterY = mHeight / 2f;
//设置图片显示位置
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) { //如果封面为为创建默认颜色
mBitmapCover = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mBitmapCover.eraseColor(mCoverColor);
}
mCoverScale = ((float) mWidth) / (float) mBitmapCover.getWidth();
//创建缩放后的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转换为位图 为BitmapShader准备
*
* @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属性

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"? 
<resources 
<declare-styleable name="play_view" 
<attr name="cover" format="integer"/ 
</declare-styleable 
</resources 

以上就是本文的全部内容,希望对大家的学习有所帮助。

0 人点赞