Android自定义SurfaceView与传感器的并用(实现自绘的指北针)
来源:互联网 发布:软件项目介绍ppt 编辑:程序博客网 时间:2024/05/21 06:40
概述:
SurfaceView是Android中极为重要的绘图容器,SurfaceView的图像绘制是放在主线程之外的另一个线程中完成的。除了绘图,SurfaceView还能播放视频。
实现方法:
实现Android的自定义SurfaceView,需要新建一个继承于SurfaceView的类,并且重写至少一种构造器,在构造器中,需要同过getHolder()方法得到一个SurfaceViewHolder类的对象holder,canvas画布通过holder调用lockCanvas()方法锁定并得到,用完画布后需要holder调用unlockCanvasAndPost(canvas)方法解锁画布。在构造方法中,holder还必须通过addCallback()方法实现监听器,监听器中需要实现的方法有三个:surfaceCreated()、surfaceChanged()、surfaceDestroyed()。自定义SurfaceView的图像需要在surfaceCreated()方法中绘制。
Demo
用SurfaceView绘制一个指北针的模型,并结合加速度传感器和地磁传感器让它动起来
/** * 自定义SurfaceView绘制一个指南针 * 继承于SurfaceView,并实现它的构造器 * 实现SurfaceHolder.Callback接口,实现surfaceCreated、surfaceChanged、surfaceDestroyed方法 */public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{ private SurfaceHolder holder; private Canvas canvas; private Path path; private Paint mPaintCircle; private Paint mPaintLine; private Paint mPaintText; private int width; private int height; private float degree; private boolean isDrawing = true; private SensorManager sensorManager; private float lastDegree; public float getDegree() { return degree; } public void setDegree(float degree) { this.degree = degree; } public MySurfaceView(Context context) { super(context); } public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); width = 1100; height = 1500; //首先得到一个SurfaceHolder对象 holder = getHolder(); //接着让holder添加Callback监听器 holder.addCallback(this); //path用于画指针 path = new Path(); //画外环的画笔 mPaintCircle = new Paint(); mPaintCircle.setColor(Color.BLACK); mPaintCircle.setStyle(Paint.Style.FILL_AND_STROKE); mPaintCircle.setStrokeWidth(30); //画刻度线的画笔 mPaintLine = new Paint(); mPaintLine.setColor(Color.WHITE); mPaintLine.setStyle(Paint.Style.FILL); mPaintLine.setStrokeWidth(10); //画文本的画笔 mPaintText = new Paint(); mPaintText.setTextSize(70); mPaintLine.setTextAlign(Paint.Align.LEFT); mPaintText.setColor(Color.WHITE); //sensorManager用于管理传感器 sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); //地磁传感器 Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); //加速度传感器 Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //分别给两种传感器注册监听器 sensorManager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME); } @Override public void surfaceCreated(final SurfaceHolder holder) { /** * 在一个线程中进行绘制 */ new Thread(new Runnable() { @Override public void run() { //用一个无限循环,便于随时改变图形 while(isDrawing) { canvas = holder.lockCanvas(); canvas.drawColor(Color.BLUE); canvas.drawCircle(width / 2, height / 2, 400, mPaintCircle); for (int i = 0; i <= 35; i++) { canvas.save(); canvas.rotate(10*i+degree,width / 2, height / 2); canvas.drawLine(width / 2, height / 2 - 400, width / 2, height / 2 - 400 + 50, mPaintLine); if (i == 0) { canvas.drawText("N", width / 2, height / 2 - 400 - 40, mPaintText); }else if(i == 8){ canvas.drawText("E" , width / 2, height / 2 -400 -40, mPaintText); }else if(i == 17){ canvas.drawText("S" , width / 2, height / 2 -400 -40, mPaintText); }else if(i == 26){ canvas.drawText("W" , width / 2, height / 2 -400 -40, mPaintText); } canvas.restore(); } //每当degree发生改变,canvas画布都会转动相应的角度 canvas.rotate(degree,width / 2, height / 2); //绘制指针 path.moveTo(width / 2 - 10, height / 2); path.lineTo(width / 2, height / 2 - 150); path.lineTo(width / 2 + 10, height / 2); path.close(); canvas.drawPath(path, mPaintLine); //每次用完canvas,都要调用unlockCanvasAndPost()解锁一次 holder.unlockCanvasAndPost(canvas); } } }).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } /**注销 * 当调用surfaceDestroyed方法时,停止线程中的死循环,并且sensorManager的监听器 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { isDrawing = false; if(sensorManager!=null){ sensorManager.unregisterListener(listener); } } //监听传感器 private SensorEventListener listener = new SensorEventListener() { float[] accelerometerValues = new float[3]; float[] magneticValues = new float[3]; @Override public void onSensorChanged(SensorEvent event) { if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){ accelerometerValues = event.values.clone(); }else if(event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){ magneticValues = event.values.clone(); } float[] R = new float[9]; float[] values = new float[3]; //得到包含旋转矩阵的R数组 SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues); //计算手机的旋转数据,并将参数存入values数组 SensorManager.getOrientation(R, values); //将弧度转换为角度 degree = -(float) Math.toDegrees(values[0]); if(Math.abs(degree-lastDegree)>10){ lastDegree = degree; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } };}
在xml布局中定义这个自定义SurfaceView
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.example.administrator.selfishgroupview.my_groupview.MySurfaceView android:id="@+id/my_surfaceView" android:layout_width="match_parent" android:layout_height="match_parent"/></LinearLayout>
主活动:
public class SouthArrowActivity extends Activity { private MySurfaceView mySurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_source); mySurfaceView = (MySurfaceView) findViewById(R.id.my_surfaceView); }}
结果演示(必须在真机上才能运行):
看到没,我的指北针多么简约大气。
我们猿类工作压力大,很需要有自己的乐趣,于是乎,我开通了音乐人账号,以后的作品将会上传到我的音乐人小站上。如果这篇博客帮助到您,希望您能多关注,支持,鼓励我将创作进行下去,同时也祝你能在工作和生活乐趣两发面都能出彩!
网易云音乐人,直接打开客户端搜索音乐人 “星河河”
豆瓣音乐人地址:https://site.douban.com/chuxinghe/ 星河河
0 0
- Android自定义SurfaceView与传感器的并用(实现自绘的指北针)
- android 传感器的实现
- Android自定义view--SurfaceView实现墨迹天气的风车效果
- 实现自定义View,SurfaceView的基本框架
- Android自定义控件之SurfaceView的使用
- 磁场传感器(指北针)
- 一种无线传感器网络自组网协议的研究与实现
- 出图时加上指北针的代码
- Android传感器利用Senser实现不同的传感器
- Android使用自定义View继承SurfaceView实现动态折线图的绘制
- Android使用自定义View继承SurfaceView实现动态折线图的绘制
- Android 项目需求Camera + SurfaceView实现自定义拍照,遇到的问题
- Android视图SurfaceView的实现原理分析
- Android视图SurfaceView的实现原理分析
- Android视图SurfaceView的实现原理分析
- Android视图SurfaceView的实现原理分析
- Android视图SurfaceView的实现原理分析
- Android视图SurfaceView的实现原理分析
- C语言程序初体验-第四课-第二题:计算并联电阻R的阻值
- Ubuntu下添加开机启动项的2种方法
- iOS激情详解之集合视图
- yii 2.0 windows环境搭建
- 面试问题总结之java 深拷贝浅拷贝
- Android自定义SurfaceView与传感器的并用(实现自绘的指北针)
- Mac上配置Gradle
- mysql datetime,timestamp,date
- UVa 12464 - Professor Lazy, Ph.D.
- 用xutils或imageloader加载网络图片实现轮播效果
- hdu 1147 Pick-up sticks(求是否有交点)
- 【ROS学习记录——1】ROS学习资料记录
- 朗国9个月总结与新公司展望
- 关于Java的点点滴滴(1)——Static关键字