首页 > 系统 > Android > 正文

Android自定义View实现QQ音乐中圆形旋转碟子

2019-12-12 05:08:32
字体:
来源:转载
供稿:网友

QQ音乐中圆形旋转碟子

思路分析:
1、在onMeasure中测量整个View的宽和高后,设置宽高
2、获取我们res的图片资源后,在ondraw方法中进行绘制圆形图片
3、通过Handler发送Runnable来启动旋转线程(如果只想做圆形头像的话,这步可以去掉)
4、在布局中使用我们的View

效果图:


贴出我们的变量信息:

//view的宽和高 int mHeight = 0; int mWidth = 0; //圆形图片 Bitmap bitmap = null; //圆形图片的真实半径 int radius = 0; //旋转动画的矩形 Matrix matrix = new Matrix(); //旋转动画的角度 int degrees = 0; 

步骤一:测量整个View的宽和高后,设置宽高

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  //测量整个View的宽和高  mWidth = measuredWidth(widthMeasureSpec);  mHeight= measuredHeight(heightMeasureSpec);  setMeasuredDimension(mWidth, mHeight); }  private int measuredWidth(int widthMeasureSpec) {  int Mode = MeasureSpec.getMode(widthMeasureSpec);  int Size = MeasureSpec.getSize(widthMeasureSpec);  if (Mode == MeasureSpec.EXACTLY) {   mWidth = Size;  } else {   //由图片决定宽度   int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth();   if (Mode == MeasureSpec.AT_MOST) {    //由图片和Padding决定宽度,但是不能超过View的宽    mWidth = Math.min(value, Size);   }  }  return mWidth; }  private int measuredHeight(int heightMeasureSpec) {  int Mode = MeasureSpec.getMode(heightMeasureSpec);  int Size = MeasureSpec.getSize(heightMeasureSpec);  if (Mode == MeasureSpec.EXACTLY) {   mHeight = Size;  } else {   //由图片决定高度   int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight();   if (Mode == MeasureSpec.AT_MOST) {    //由图片和Padding决定高度,但是不能超过View的高    mHeight = Math.min(value, Size);   }  }  return mHeight; } 

步骤二:获取我们res的图片资源后,在ondraw方法中进行绘制圆形图片

//获取res的图片资源 bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  canvas.concat(matrix);  //真实的半径必须是View的宽高最小值  radius = Math.min(mWidth, mHeight);  //如果图片本身宽高太大,进行相应的缩放  bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);  //画圆形图片  canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null);  matrix.reset(); }  private Bitmap createCircleImage(Bitmap source, int radius) {  Paint paint = new Paint();  paint.setAntiAlias(true);  Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);  //产生一个同样大小的画布  Canvas canvas = new Canvas(target);  //首先绘制圆形  canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);  //使用SRC_IN模式显示后画图的交集处  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  //绘制图片,从(0,0)画  canvas.drawBitmap(source, 0, 0, paint);  return target; } 

步骤三:通过Handler发送Runnable来启动旋转线程

//开始旋转 mHandler.post(runnable); [java] view plain copy 在CODE上查看代码片派生到我的代码片//-----------旋转动画----------- Handler mHandler = new Handler(); Runnable runnable = new Runnable() {  @Override  public void run() {   matrix.postRotate(degrees++, radius / 2, radius / 2);   //重绘   invalidate();   mHandler.postDelayed(runnable, 50);  } }; 

步骤四:在布局中使用我们的View

<com.handsome.cycle.MyCycleView  android:layout_width="wrap_content"  android:layout_height="wrap_content" /> 

下面是整个类的源码

public class MyCycleView extends View {   //view的宽和高  int mHeight = 0;  int mWidth = 0;  //圆形图片  Bitmap bitmap = null;  //圆形图片的真实半径  int radius = 0;  //旋转动画的矩形  Matrix matrix = new Matrix();  //旋转动画的角度  int degrees = 0;   //-----------旋转动画-----------  Handler mHandler = new Handler();  Runnable runnable = new Runnable() {   @Override   public void run() {    matrix.postRotate(degrees++, radius / 2, radius / 2);    //重绘    invalidate();    mHandler.postDelayed(runnable, 50);   }  };   public MyCycleView(Context context) {   super(context);   initView();  }   public MyCycleView(Context context, AttributeSet attrs) {   super(context, attrs);   initView();  }   public MyCycleView(Context context, AttributeSet attrs, int defStyleAttr) {   super(context, attrs, defStyleAttr);   initView();  }   public void initView() {   //获取res的图片资源   bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);   //开始旋转   mHandler.post(runnable);  }   @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   super.onMeasure(widthMeasureSpec, heightMeasureSpec);   //测量整个View的宽和高   mWidth = measuredWidth(widthMeasureSpec);   mHeight = measuredHeight(heightMeasureSpec);   setMeasuredDimension(mWidth, mHeight);  }   private int measuredWidth(int widthMeasureSpec) {   int Mode = MeasureSpec.getMode(widthMeasureSpec);   int Size = MeasureSpec.getSize(widthMeasureSpec);   if (Mode == MeasureSpec.EXACTLY) {    mWidth = Size;   } else {    //由图片决定宽度    int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth();    if (Mode == MeasureSpec.AT_MOST) {     //由图片和Padding决定宽度,但是不能超过View的宽     mWidth = Math.min(value, Size);    }   }   return mWidth;  }   private int measuredHeight(int heightMeasureSpec) {   int Mode = MeasureSpec.getMode(heightMeasureSpec);   int Size = MeasureSpec.getSize(heightMeasureSpec);   if (Mode == MeasureSpec.EXACTLY) {    mHeight = Size;   } else {    //由图片决定高度    int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight();    if (Mode == MeasureSpec.AT_MOST) {     //由图片和Padding决定高度,但是不能超过View的高     mHeight = Math.min(value, Size);    }   }   return mHeight;  }   @Override  protected void onDraw(Canvas canvas) {   super.onDraw(canvas);   canvas.concat(matrix);   //真实的半径必须是View的宽高最小值   radius = Math.min(mWidth, mHeight);   //如果图片本身宽高太大,进行相应的缩放   bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);   //画圆形图片   canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null);   matrix.reset();  }   private Bitmap createCircleImage(Bitmap source, int radius) {   Paint paint = new Paint();   paint.setAntiAlias(true);   Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);   //产生一个同样大小的画布   Canvas canvas = new Canvas(target);   //首先绘制圆形   canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);   //使用SRC_IN模式显示后画图的交集处   paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));   //绘制图片,从(0,0)画   canvas.drawBitmap(source, 0, 0, paint);   return target;  } } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表