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

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; } }

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

时间: 2024-11-05 17:23:34

Android自定义View实现QQ音乐中圆形旋转碟子的相关文章

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

QQ音乐中圆形旋转碟子 思路分析: 1.在onMeasure中测量整个View的宽和高后,设置宽高 2.获取我们res的图片资源后,在ondraw方法中进行绘制圆形图片 3.通过Handler发送Runnable来启动旋转线程(如果只想做圆形头像的话,这步可以去掉) 4.在布局中使用我们的View 效果图: 贴出我们的变量信息: //view的宽和高 int mHeight = 0; int mWidth = 0; //圆形图片 Bitmap bitmap = null; //圆形图片的真实半径

Android自定义View 仿QQ侧滑菜单的实现代码

先看看QQ的侧滑效果 分析一下 先上原理图(不知道能否表达的清楚 ==) -首先这里使用了 Android 的HorizontalScrollView 水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图 - 这个容器里面有一个父布局(一般用LinerLayout,本demo用的是),这个父布局里面有且只有两个子控件(布局),初始状态菜单页的位置在Y轴上存在偏移这样可以就可以形成主页叠在菜单页的上方的视觉效果:然后在滑动的过程程中 逐渐修正偏移,最后菜单页和主页并排排列.原理搞清了实现起来

Android自定义View之绘制音乐播放器示波器

周末玩的有点嗨,没更新博客了,今天补上,这个示波器是在大学的时候老师教的,但是出来工作一直没有用到过,渐渐的也就忘记了,现在重新学习一下.来看看效果图: 这里是一个自定义的柱状图,然后有一个按钮,点击按钮的时候,这里柱子会不停的运动,类似于音乐播放器里示波器的跳动. 跟前面几个自定义view的方式类似,重写了onSizeChange()方法和onDraw()方法  先列一下我们要用到的变量 Paint mPaint; mWidth; mRectWidth; mRectHeight; mRectC

Android自定义View仿QQ健康界面_Android

最近一直在学习自定义View相关的知识,今天给大家带来的是QQ健康界面的实现.先看效果图: 可以设置数字颜色,字体颜色,运动步数,运动排名,运动平均步数,虚线下方的蓝色指示条的长度会随着平均步数改变而进行变化.整体效果还是和QQ运动健康界面很像的. 自定义View四部曲,一起来看看怎么实现的. 1.自定义view的属性: <?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定

Android自定义View仿QQ健康界面

最近一直在学习自定义View相关的知识,今天给大家带来的是QQ健康界面的实现.先看效果图: 可以设置数字颜色,字体颜色,运动步数,运动排名,运动平均步数,虚线下方的蓝色指示条的长度会随着平均步数改变而进行变化.整体效果还是和QQ运动健康界面很像的. 自定义View四部曲,一起来看看怎么实现的. 1.自定义view的属性: <?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定

Android自定义View实现QQ运动积分转盘抽奖功能

因为偶尔关注QQ运动, 看到QQ运动的积分抽奖界面比较有意思,所以就尝试用自定义View实现了下,原本想通过开发者选项查看下界面的一些信息,后来发现积分抽奖界面是在WebView中展示的,应该是在H5页面中用js代码实现的,暂时不去管它了. 这里的自定义View针对的是继承自View的情况,你可以将Canvas想象为画板, Paint为画笔,自定义View的过程和在画板上用画笔作画其实类似,想象在画板上作画的过程,你要画一个多大图形(对应View的测量 onMeasure方法),你要画什么样的图

Android自定义View仿QQ等级天数进度

最近一直都在看自定义View这一块.差不多一个星期了吧.这个星期坚持每天更新博客,感觉自己的技术也有点突破,对自定义View的计算也有了更深的认识. 今天看到手机一个成长天数进度的控件,觉得挺有意思的,于是想自己也写一个.效果如下: 由图可以知道,这里面有很多个元素,首先是背景的矩形区域,其次就是两个环形,然后三个Text文本.其实不复杂,我们一点一点的去实现. 首先呢,画矩形背景.这里用到一个RectF的类,这个类包含一个矩形的四个单精度浮点坐标.矩形通过上下左右4个边的坐标来表示一个矩形.这

Android自定义View模仿QQ讨论组头像效果

首先来看看我们模仿的效果图,相信对于使用过QQ的人来说都不陌生,效果图如下: 在以前的一个项目中,需要实现类似QQ讨论组头像的控件,只是头像数量和布局有一小点不一样:一是最头像数是4个,二是头像数是2个时的布局是横着排的.其实当时GitHub上就有类似的开源控件,只是那个控件在每一次绘制View的时候都会新创建一些Bitmap对象,这肯定是不可取的,而且那个控件头像输入的是Bitmap对象,不满足需求.所以只能自己实现一个了.实现的时候也没有过多的考虑,传入头像Drawable对象,根据数量排列

Android自定义View研究--View中的原点坐标和XML中布局自定义View时View触摸原点问题

这里只做个汇总~.~独一无二 文章出处:http://blog.csdn.net/djy1992/article/details/9715047 Android自定义View研究--View中的原点坐标相关问题 我们自定义了View,但是有没想过一个问题,就是View中的(0,0)坐标,也就是原点坐标在哪??我们是不是有时候很困惑,接下来我们就来研究View中的原点坐标相关的问题. 一.new DuView时View的原点 我们通过从View中绘制一条从原点到右下角的线来看看这个View中的原点