Android UI 之自定义RadarView——高仿微信雷达扫描
2015-12-07 17:40
579 查看
最近看了一个视频讲了一种微信雷达扫描的实现方案,借鉴了一下,自己也写一个玩玩,与大家分享一下。基本想出来三种解决方案,根据不同需求情况选择即可。
方案一实现思路(通用):
1.自定义view
2.重写onDraw()方法
3.画四个无锯齿空心圆
4.画以最大圆为半径的实心渐变圆
5.创建矩阵,旋转画布,重绘,并用Handler实现循环
本以为微信也是这么实现的,结果发现透明还是照微信差一点点,继续看微信apk解压的资源文件发现,原来连四个空心圆+实心渐变圆是一张图片,害的我还画了半天调比例。所以就有下面的第二种方案。
方案二实现思路(适用于最大圆直径小于屏幕宽度的情况):
1.四个空心圆+实心圆为一张图片
2.普通ImageView+xml旋转动画
旋转动画:
repeatCount设置成-1保证循环转动,从0度转到359,duration时长10秒,绕中心点旋转。
加载动画:
ImageView正常布局就行了,这样就齐活了,就可以用了,但是有个问题,不方便设置让最大的圆直径超过屏幕宽度,可以设置 android:scaleType="centerCrop",但是虽然超出了屏幕,布局效果也微信一至了,但是问题就来了,超出后旋转,图片是长方形的,圆图被截取了,所以这种用法适用于最大圆直径小于屏幕宽度的情况。所以虽然简单但美中不足,于是设想将两种方案结合起来,方案三就诞生了。
方案三实现思路(通用):
1.四个空心圆+实心圆为一张图片
2.自定义ImageView
3.利用方案一的方法用矩阵让image转起来
很简单吧,好了,以上就是三种实现方案了,根据自己的实际需要选择吧,同时如果有更好的解决方法,也欢迎交流~
Demo源码 :http://download.csdn.net/detail/itjianghuxiaoxiong/9331925
方案一实现思路(通用):
1.自定义view
2.重写onDraw()方法
3.画四个无锯齿空心圆
4.画以最大圆为半径的实心渐变圆
5.创建矩阵,旋转画布,重绘,并用Handler实现循环
package com.ml512.radarview; import com.ml512.radardemo.R; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Shader; import android.graphics.SweepGradient; import android.os.Handler; import android.util.AttributeSet; import android.view.View; /** * 2015/12/06 22:49 * @author ITjianghuxiaoxiong * http://blog.csdn.net/itjianghuxiaoxiong */ @SuppressLint("DrawAllocation") public class RadarView extends View { private int w, h;// 获取控件宽高 private Paint mPaintLine;// 画雷达圆线 private Paint mPaintSolid;// 画雷达渐变实心圆 private Matrix matrix; private int degrees; private Handler mHandler = new Handler(); private Runnable mRunnable = new Runnable() { @Override public void run() { degrees++; matrix.postRotate(degrees, w / 2, h / 2);//旋转矩阵 RadarView.this.invalidate();// 重绘 mHandler.postDelayed(mRunnable, 55); } }; public RadarView(Context context) { this(context, null); } public RadarView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RadarView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setBackgroundResource(R.drawable.radar_bg);//雷达的背景图片(紫色满天星,可以在微信APP中直接找到图片资源) initPaint(); mHandler.postDelayed(mRunnable,500); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); w = getMeasuredWidth();//获取view的宽度 h = getMeasuredHeight();//获取view的高度 } /** * 初始化画笔 */ private void initPaint() { mPaintLine = new Paint(); mPaintLine.setColor(Color.parseColor("#CCA1A1A1"));// 设置画笔 mPaintLine.setStrokeWidth(1);// 设置画笔宽度 mPaintLine.setAntiAlias(true);// 消除锯齿 mPaintLine.setStyle(Style.STROKE);// 设置空心 mPaintSolid = new Paint(); mPaintSolid.setAntiAlias(true);// 消除锯齿 mPaintSolid.setStyle(Style.FILL);//实心圆 matrix = new Matrix();//创建组件 } @Override protected void onDraw(Canvas canvas) { //四个空心圆 canvas.drawCircle(w / 2, h / 2, w / 6, mPaintLine); canvas.drawCircle(w / 2, h / 2, 5 * w / 14, mPaintLine); canvas.drawCircle(w / 2, h / 2, 12 * w / 20, mPaintLine); canvas.drawCircle(w / 2, h / 2, 9 * w / 11, mPaintLine); //渐变 Shader mShader = new SweepGradient(w / 2, h / 2, Color.TRANSPARENT, Color.parseColor("#33FFFFFF")); mPaintSolid.setShader(mShader); canvas.setMatrix(matrix); canvas.drawCircle(w / 2, h / 2, 9 * w / 11, mPaintSolid); matrix.reset();//重置矩阵,避免累加,越转越快 super.onDraw(canvas); } }
本以为微信也是这么实现的,结果发现透明还是照微信差一点点,继续看微信apk解压的资源文件发现,原来连四个空心圆+实心渐变圆是一张图片,害的我还画了半天调比例。所以就有下面的第二种方案。
方案二实现思路(适用于最大圆直径小于屏幕宽度的情况):
1.四个空心圆+实心圆为一张图片
2.普通ImageView+xml旋转动画
旋转动画:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <rotate android:duration="10000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:repeatCount="-1" android:toDegrees="359"/> </set>
repeatCount设置成-1保证循环转动,从0度转到359,duration时长10秒,绕中心点旋转。
加载动画:
// 加载动画 Animation rotateAnim = AnimationUtils.loadAnimation(this, R.anim.radar_rotate_anim); LinearInterpolator lin = new LinearInterpolator();// 匀速旋转 rotateAnim.setInterpolator(lin); ImageView radarImage = (ImageView) findViewById(R.id.image_radar); radarImage.startAnimation(rotateAnim);
ImageView正常布局就行了,这样就齐活了,就可以用了,但是有个问题,不方便设置让最大的圆直径超过屏幕宽度,可以设置 android:scaleType="centerCrop",但是虽然超出了屏幕,布局效果也微信一至了,但是问题就来了,超出后旋转,图片是长方形的,圆图被截取了,所以这种用法适用于最大圆直径小于屏幕宽度的情况。所以虽然简单但美中不足,于是设想将两种方案结合起来,方案三就诞生了。
方案三实现思路(通用):
1.四个空心圆+实心圆为一张图片
2.自定义ImageView
3.利用方案一的方法用矩阵让image转起来
package com.ml512.radarview; import com.ml512.radardemo.R; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.os.Handler; import android.util.AttributeSet; import android.widget.ImageView; /** * 2015/12/06 22:49 * @author ITjianghuxiaoxiong * http://blog.csdn.net/itjianghuxiaoxiong */ @SuppressLint("DrawAllocation") public class RadarImageView extends ImageView { private int w, h;// 获取控件宽高 private Matrix matrix; private int degrees; private Handler mHandler = new Handler(); private Runnable mRunnable = new Runnable() { @Override public void run() { degrees++; matrix.postRotate(degrees, w / 2, h / 2); RadarImageView.this.invalidate();// 重绘 mHandler.postDelayed(mRunnable, 50); } }; public RadarImageView(Context context) { this(context, null); } public RadarImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RadarImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); w = getMeasuredWidth();//获取view的宽度 h = getMeasuredHeight();//获取view的高度 } /** * 初始化 */ private void init() { setBackgroundResource(R.drawable.radar_bg); matrix = new Matrix(); mHandler.postDelayed(mRunnable,500); } @Override protected void onDraw(Canvas canvas) { canvas.setMatrix(matrix); super.onDraw(canvas); matrix.reset(); } }布局引用:
<com.ml512.radarview.RadarImageView android:id="@+id/image_radar" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:padding="15dp" android:src="@drawable/wx_radar_imgae"/>
很简单吧,好了,以上就是三种实现方案了,根据自己的实际需要选择吧,同时如果有更好的解决方法,也欢迎交流~
Demo源码 :http://download.csdn.net/detail/itjianghuxiaoxiong/9331925
相关文章推荐
- UIScrollView循环滚动(三张图片循环滚动)
- 颜色转换 IOS中十六进制的颜色转换为UIColor
- Errors running builder 'Validation' on project ** java.lang.NullPointerException
- PHP文件加载include,require。
- MiniUI 在线示例
- request.getParameter() 和request.getAttribute() 区别
- Andriod Studio Clear Project或Rebuild Project出错
- 转:Java多线程-工具篇-BlockingQueue
- Java:DocumentBuilderFactory调用XML的方法实例
- jboss8+EJB3+MDB Queue
- iOS 【UIKit-UINavigationController详解与使用(一)添加UIBarButtonItem】
- iOS 【UIKit-UIBarButtonItem 的四种初始化方式】
- SharePoint 2013 BI--Power Query for SharePoint
- iOS开发UI篇—iOS开发中三种简单的动画设置
- x01.CodeBuilder: 生成代码框架
- Uincode和ASCLL
- BlockingQueue的使用
- java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission:
- 根据内容自动调节cell的高度
- 创建圆角 抛出一个错误:二元运算符“|”不能用于两个UIRectCorner操作数