Android 实现指南针效果
Android 实现指南针效果
前一段时间在做指南针,于是想偷偷懒.在网上直接找一个Demo.然后改改旧差不多了.可是看到的效果却和预期的差太多了,所以就不得不自己撸一个:
大致上会用到内容
- 自定义View
- GPS定位模块
- 方向传感器
开始,创建一个view
- 先写一个类继承view
- 不断对OnDraw事件进行重绘
- 传入方向
OK.那么新建一个DirectionView 来继承view
public class DirectionView extends View {}
那么绘制需要用到什么。用到画笔。宽度。等等一系列参数。
public class DirectionView extends View {/*** 圆环使用* */private Paint mRingPaint;private Paint mCententPaint; //绘制中心实线的画布/*** 圆环半径 根据view的宽度计算* */private int mRadius = 200;/*** 圆环的中心点 -- 画圆环和旋转画布时需要使用* */private int x, y;/*** 圆环动画使用 -- 与mRingPaint唯一不同得方在于颜色* */private Paint mRingAnimPaint;/*** 圆环大小 矩形* */private RectF mRectf;private Context mContext;/*** 圆环 宽度* */private final int mHeartPaintWidth = 50;/*** 圆环动画开始时 画弧的偏移量* */private int mAnimAngle = -1;}
初始化部分我们先不管。看到效果图.我们是不是需要先将360度的齿轮画好。
这里我们就需要对ondraw 来操作了。
绘制嘛。必须要画板嘛
canvas.setDrawFilter(mDrawFilter);//在canvas上抗锯齿//由于drawArc默认从x轴开始画,因此需要将画布旋转或者绘制角度旋转,2种方案//int level = canvas.save();//先绘制竖线canvas.drawLine(x,mRectf.top + 30, x , mRectf.top - 60,mCententPaint);//绘制中心线canvas.drawLine(x,y-80,x,y + 80,mCententPaint);canvas.drawLine(x - 80,y,x + 80, y ,mCententPaint);canvas.rotate(rotate, x, y);// 旋转的时候一定要指明中心for (int i = 0; i < 360; i += 3) {canvas.drawArc(mRectf, i, 1, false, mRingPaint);}
这里喔们把360度的齿轮绘制了。大致上是每隔3度绘制一条。
那么绘制齿轮之后。我们是不是需要绘制东西南北了。
mCententPaint.setTextSize(50);mCententPaint.setColor(Color.RED);canvas.drawText("北",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);mCententPaint.setColor(Color.BLACK);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心canvas.drawText("东",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心canvas.drawText("南",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心canvas.drawText("西",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心mCententPaint.setTextSize(30);for (int i = 0; i < 360; i += 3) {if(i == 0|| i == 30 || i ==60 || i ==90 || i ==120 || i == 150 || i == 180 || i == 210 || i == 240 || i == 270 || i == 300 || i == 330 || i== 0){canvas.drawText(""+i,x,mRectf.top - mHeartPaintWidth ,mCententPaint);canvas.rotate(30, x, y);// 旋转的时候一定要指明中心}}
那么整个代码就是:
package com.jonkming.easyui.hardware.compass.ui;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;import com.jonkming.easyui.R;/*** 指南针的自定位View
* @Title: DirectionView.java
* @Package com.jonkming.easyui.hardware.compass.ui
* @author HuangMingming
* @date 2016/11/10 19:16
* @version V1.0
*/
public class DirectionView extends View {/*** 圆环使用* */private Paint mRingPaint;private Paint mCententPaint; //绘制中心实线的画布/*** 圆环半径 根据view的宽度计算* */private int mRadius = 200;/*** 圆环的中心点 -- 画圆环和旋转画布时需要使用* */private int x, y;/*** 圆环动画使用 -- 与mRingPaint唯一不同得方在于颜色* */private Paint mRingAnimPaint;/*** 圆环大小 矩形* */private RectF mRectf;private Context mContext;/*** 圆环 宽度* */private final int mHeartPaintWidth = 50;/*** 圆环动画开始时 画弧的偏移量* */private int mAnimAngle = -1;public DirectionView(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);this.mContext = context;init();}public DirectionView(Context context, AttributeSet attrs){this(context, attrs, 0);this.mContext = context;init();}public DirectionView(Context context){this(context, null);this.mContext = context;init();}private void init(){mRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mRingPaint.setStrokeWidth(mHeartPaintWidth);mRingPaint.setStyle(Paint.Style.STROKE);mRingAnimPaint = new Paint(mRingPaint);mRingAnimPaint.setColor(Color.WHITE);//初始化心跳曲线mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);mCententPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mCententPaint.setColor(Color.BLACK);mCententPaint.setStrokeWidth(3);}/*** canvas抗锯齿开启需要* */private DrawFilter mDrawFilter;@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);x = w / 2;y = h / 2;mRadius = w / 2 - mHeartPaintWidth * 3; //因为制定了Paint的宽度,因此计算半径需要减去这个mRectf = new RectF(x - mRadius, y - mRadius, x + mRadius, y + mRadius);}public float rotate = 0;@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.setDrawFilter(mDrawFilter);//在canvas上抗锯齿//由于drawArc默认从x轴开始画,因此需要将画布旋转或者绘制角度旋转,2种方案//int level = canvas.save();//先绘制竖线canvas.drawLine(x,mRectf.top + 30, x , mRectf.top - 60,mCententPaint);//绘制中心线canvas.drawLine(x,y-80,x,y + 80,mCententPaint);canvas.drawLine(x - 80,y,x + 80, y ,mCententPaint);canvas.rotate(rotate, x, y);// 旋转的时候一定要指明中心for (int i = 0; i < 360; i += 3) {canvas.drawArc(mRectf, i, 1, false, mRingPaint);}mCententPaint.setTextSize(50);mCententPaint.setColor(Color.RED);canvas.drawText("北",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);mCententPaint.setColor(Color.BLACK);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心canvas.drawText("东",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心canvas.drawText("南",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心canvas.drawText("西",x,mRectf.top + mHeartPaintWidth + 50,mCententPaint);canvas.rotate(90, x, y);// 旋转的时候一定要指明中心mCententPaint.setTextSize(30);for (int i = 0; i < 360; i += 3) {if(i == 0|| i == 30 || i ==60 || i ==90 || i ==120 || i == 150 || i == 180 || i == 210 || i == 240 || i == 270 || i == 300 || i == 330 || i== 0){canvas.drawText(""+i,x,mRectf.top - mHeartPaintWidth ,mCententPaint);canvas.rotate(30, x, y);// 旋转的时候一定要指明中心}}}
}
绘制完了之后我们是不是要写界面代码了。这里xml 布局就不贴出来了。后面可以直接去github 去看看
主界面主要的作用就是对sensor监听。并返回方向的角度。然后对上面定义的view进行方向赋值。然后通知view 重绘就可以了
@Overrideprotected void onResume() {/*** 获取方向传感器* 通过SensorManager对象获取相应的Sensor类型的对象*/Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_ORIENTATION);//应用在前台时候注册监听器manager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_GAME);super.onResume();}@Overrideprotected void onPause() {//应用不在前台时候销毁掉监听器manager.unregisterListener(listener);super.onPause();}private final class SensorListener implements SensorEventListener {private float predegree = 0;@Overridepublic void onSensorChanged(SensorEvent event) {/*** values[0]: x-axis 方向加速度values[1]: y-axis 方向加速度values[2]: z-axis 方向加速度*/float degree = event.values[0];// 存放了方向值predegree=-degree;mCompassDegreeTxt.setText(""+((int)degree)+"°");mCompassDirectionTxt.setText(formatPredegree(degree));directionView.rotate = predegree;directionView.postInvalidate();}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}}
Android 实现指南针效果相关推荐
- android 下拉窗帘,Android 窗帘(Curtain)效果二之波浪式动态扭曲效果
上一篇文章已经实现了如何把一张图片扭曲成波浪效果,那么这一篇文章我们介绍如何动态调整系数,去改变波浪图片的皱褶成度.我们自一次观察下图morning routine的效果: 仔细观察我们发现,当往右滑 ...
- Android m 自定义下拉菜单,Android实现动画效果的自定义下拉菜单功能
我们在购物APP里面设置收货地址时,都会有让我们选择省份及城市的下拉菜单项.今天我将使用Android原生的 Spinner 控件来实现一个自定义的下拉菜单功能,并配上一个透明渐变动画效果. 要实现的 ...
- android 卡片旋转动画,Android 卡片翻转效果
Android 卡片翻转效果使用的Cramre来完成 记录一下: 一个好用的3D旋转工具类 oid.graphics.Matrix; import android.util.Log; import a ...
- 【Android源代码下载】收集整理android界面UI效果源码
在Android开发中,Android界面UI效果设计一直都是很多童鞋关注的问题,今天给大家分享下大神收集整理的多个android界面UI效果,都是源码,都是干货,贡献给各位网友! 话不多说,直接上效 ...
- android 动态创建view,react-native动态创建Android View 无效果
问题描述 react-native动态创建Android View 无效果,我想在react-native里面直接点击函数进行创建,也就是通过module中的方法创建View 问题出现的环境背景及自己 ...
- android 移动拼图效果实现
android 移动拼图效果实现 代码地址: https://github.com/tingsky9985/Puzzle
- android中倒计时动画,Android实现倒计时效果
本文实例为大家分享了Android实现倒计时效果的具体代码,供大家参考,具体内容如下 一个倒计时的效果 先看效果图: 直接上代码: 这里是关于倒计时 -天时分秒-的逻辑判断 /** * 倒计时计算 * ...
- Android中指南针的实现
其实这篇博客不是做真正的指南针,因为真正的指南针需要做一个完整的自定义控件来指示方向.我们这里只是简单通过代码获取用户手机头部指向的方向.这个功能往往在我们定位获取的时候,用户方向变更后进行采集.车辆 ...
- Android学习-指南针(方向传感器)
Android学习-指南针 效果图(背景图片网上随便找的): 1.编写布局文件activity_main.xml文件 主要放一个东南西北方向图片,一个指针图片用来指明方向 <?xml versi ...
最新文章
- linux vim模板,FreeBSD8下的vim配置模板
- Activity之间切换 以及传值
- svn: Can't convert string from 'UTF-8' to native
- python函数:函数参数,常用函数工具
- 仿真的数据能否用来深度学习_数字孪生弥合了深度学习的数据鸿沟
- 【跨域问题】Vue简单封装axios—解决post请求后端接收不到参数问题
- Bootstrap Table踩坑——设置多级表头后只显示第一级表头问题解决办法
- NPOI导出excel(带图片)
- Mac下安装Flink的local模式(flink-1.5.2)
- iis6扩展php_windows2003server中iis6多版本php配置方法
- (转)STORM启动与部署TOPOLOGY
- Flash: 涅磐与重生
- MyBatis-Plus updateById方法更新不了空字符串/null解决方法
- python爬虫:获取12306网站火车站对应三字码
- Vuex 的简单模拟、了解Vuex
- Python基础(二)
- pb函数库之字符串操作函数
- 广州图普网络科技2017校园招聘简章
- 两个网段共享打印机_不同ip段共享打印机设置方法
- 中国工程院院士刘韵洁:中国未来网络创新环境CENI的探索
热门文章
- [人工智能-深度学习-43]:输入预处理 - 规范化Normalization、标准化Standardization、正态分布、算术平均、方差
- 【Python】多图形混合排版,如何在Matplotlib/Seaborn中实现?
- python123测验答案第十周_智慧职教mooc的APPPython程序设计(常州工业职业技术学院)章节测验答案...
- 含有未知中间变量同时需要传递其他中间变量的微分方程参数拟合
- 快手亮相第七届全球数字营销峰会,以全域内容营销驱动商业新增长
- 面试记录:光大银行北京分行金融科技岗实习
- 《MySQL系列-开发相关》MySQL新建数据库表并存储2010年到2030年的日期
- Maxon CINEMA 4D Studio R26.014 三维建模软件C4D R26
- matlab之向数据点添加文本说明函数text
- 世界上什么人最重要?什么事最重要?什么时间最重要?