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 实现指南针效果相关推荐

  1. android 下拉窗帘,Android 窗帘(Curtain)效果二之波浪式动态扭曲效果

    上一篇文章已经实现了如何把一张图片扭曲成波浪效果,那么这一篇文章我们介绍如何动态调整系数,去改变波浪图片的皱褶成度.我们自一次观察下图morning routine的效果: 仔细观察我们发现,当往右滑 ...

  2. Android m 自定义下拉菜单,Android实现动画效果的自定义下拉菜单功能

    我们在购物APP里面设置收货地址时,都会有让我们选择省份及城市的下拉菜单项.今天我将使用Android原生的 Spinner 控件来实现一个自定义的下拉菜单功能,并配上一个透明渐变动画效果. 要实现的 ...

  3. android 卡片旋转动画,Android 卡片翻转效果

    Android 卡片翻转效果使用的Cramre来完成 记录一下: 一个好用的3D旋转工具类 oid.graphics.Matrix; import android.util.Log; import a ...

  4. 【Android源代码下载】收集整理android界面UI效果源码

    在Android开发中,Android界面UI效果设计一直都是很多童鞋关注的问题,今天给大家分享下大神收集整理的多个android界面UI效果,都是源码,都是干货,贡献给各位网友! 话不多说,直接上效 ...

  5. android 动态创建view,react-native动态创建Android View 无效果

    问题描述 react-native动态创建Android View 无效果,我想在react-native里面直接点击函数进行创建,也就是通过module中的方法创建View 问题出现的环境背景及自己 ...

  6. android 移动拼图效果实现

    android 移动拼图效果实现 代码地址: https://github.com/tingsky9985/Puzzle

  7. android中倒计时动画,Android实现倒计时效果

    本文实例为大家分享了Android实现倒计时效果的具体代码,供大家参考,具体内容如下 一个倒计时的效果 先看效果图: 直接上代码: 这里是关于倒计时 -天时分秒-的逻辑判断 /** * 倒计时计算 * ...

  8. Android中指南针的实现

    其实这篇博客不是做真正的指南针,因为真正的指南针需要做一个完整的自定义控件来指示方向.我们这里只是简单通过代码获取用户手机头部指向的方向.这个功能往往在我们定位获取的时候,用户方向变更后进行采集.车辆 ...

  9. Android学习-指南针(方向传感器)

    Android学习-指南针 效果图(背景图片网上随便找的): 1.编写布局文件activity_main.xml文件 主要放一个东南西北方向图片,一个指针图片用来指明方向 <?xml versi ...

最新文章

  1. linux vim模板,FreeBSD8下的vim配置模板
  2. Activity之间切换 以及传值
  3. svn: Can't convert string from 'UTF-8' to native
  4. python函数:函数参数,常用函数工具
  5. 仿真的数据能否用来深度学习_数字孪生弥合了深度学习的数据鸿沟
  6. 【跨域问题】Vue简单封装axios—解决post请求后端接收不到参数问题
  7. Bootstrap Table踩坑——设置多级表头后只显示第一级表头问题解决办法
  8. NPOI导出excel(带图片)
  9. Mac下安装Flink的local模式(flink-1.5.2)
  10. iis6扩展php_windows2003server中iis6多版本php配置方法
  11. (转)STORM启动与部署TOPOLOGY
  12. Flash: 涅磐与重生
  13. MyBatis-Plus updateById方法更新不了空字符串/null解决方法
  14. python爬虫:获取12306网站火车站对应三字码
  15. Vuex 的简单模拟、了解Vuex
  16. Python基础(二)
  17. pb函数库之字符串操作函数
  18. 广州图普网络科技2017校园招聘简章
  19. 两个网段共享打印机_不同ip段共享打印机设置方法
  20. 中国工程院院士刘韵洁:中国未来网络创新环境CENI的探索

热门文章

  1. [人工智能-深度学习-43]:输入预处理 - 规范化Normalization、标准化Standardization、正态分布、算术平均、方差
  2. 【Python】多图形混合排版,如何在Matplotlib/Seaborn中实现?
  3. python123测验答案第十周_智慧职教mooc的APPPython程序设计(常州工业职业技术学院)章节测验答案...
  4. 含有未知中间变量同时需要传递其他中间变量的微分方程参数拟合
  5. 快手亮相第七届全球数字营销峰会,以全域内容营销驱动商业新增长
  6. 面试记录:光大银行北京分行金融科技岗实习
  7. 《MySQL系列-开发相关》MySQL新建数据库表并存储2010年到2030年的日期
  8. Maxon CINEMA 4D Studio R26.014 三维建模软件C4D R26
  9. matlab之向数据点添加文本说明函数text
  10. 世界上什么人最重要?什么事最重要?什么时间最重要?