欢迎来到代码驿站!

Android代码

当前位置:首页 > 移动开发 > Android代码

Android自定义View旋转圆形图片

时间:2022-07-05 13:49:14|栏目:Android代码|点击:

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

思路:

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

效果图:

 

1、废话不多直接上代码

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属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="play_view">
  <attr name="cover" format="integer"/>
 </declare-styleable>
</resources>

上一篇:详解Flutter如何完全自定义TabBar

栏    目:Android代码

下一篇:Android实现底部导航栏效果

本文标题:Android自定义View旋转圆形图片

本文地址:http://www.codeinn.net/misctech/206854.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有