Android中的Compass(罗盘) 详解

Compass(罗盘)是一个定制的视图, 继承View类, 重写了视图的边界(onMeasure)和内容(onDraw);

如图:

以下是Compass的具体设计:

1. 创建CompassView类, 罗盘视图

位置: java->package->CompassView

package mzx.spike.compass.app;  

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;  

/**
 * Created by C.L.Wang on 14-3-16.
 */
public class CompassView extends View {  

    private float bearing; //方位  

    public void setBearing(float _bearing) {
        bearing = _bearing;
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
    }  

    public float getBearing() {
        return bearing;
    }  

    private Paint markerPaint;
    private Paint textPaint;
    private Paint circlePaint;
    private String northString;
    private String eastString;
    private String southString;
    private String westString;
    private int textHeight;  

    public CompassView(Context context) {
        super(context);
        initCompassView();
    }  

    public CompassView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initCompassView();
    }  

    public CompassView(Context context, AttributeSet attrs, int defaultStyle) {
        super(context, attrs, defaultStyle);
        initCompassView();
    }  

    private void initCompassView() {
        setFocusable(true);  

        Resources r = this.getResources();  

        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(r.getColor(R.color.background_color));
        circlePaint.setStrokeWidth(1); //笔画宽度
        circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);  

        northString = r.getString(R.string.cardinal_north);
        eastString = r.getString(R.string.cardinal_east);
        southString = r.getString(R.string.cardinal_south);
        westString = r.getString(R.string.cardinal_west);  

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(r.getColor(R.color.text_color));  

        textHeight = (int)textPaint.measureText("yY");  

        markerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        markerPaint.setColor(r.getColor(R.color.marker_color));
    }  

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredWidth = measure(widthMeasureSpec);
        int measuredHeight = measure(heightMeasureSpec);  

        int d = Math.min(measuredWidth, measuredHeight);  

        setMeasuredDimension(d, d);
    }  

    protected int measure(int measureSpec) {
        int result;  

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);  

        if (specMode == MeasureSpec.UNSPECIFIED) {
            result = 200;
        } else {
            result = specSize;
        }  

        return result;
    }  

    @Override
    protected void onDraw(Canvas canvas) {
        int mMeasuredWidth = getMeasuredWidth();
        int mMeasuredHeight = getMeasuredHeight();  

        int px = mMeasuredWidth/2;
        int py = mMeasuredHeight/2;  

        int radius = Math.min(px, py);  

        canvas.drawCircle(px, py, radius, circlePaint);  

        canvas.save();
        canvas.rotate(-bearing, px, py); //相反方向旋转  

        int textWidth = (int)textPaint.measureText("W");
        int cardinalX = px-textWidth/2;
        int cardinalY = py-radius+textHeight;  

        for (int i=0; i<24; i++) {
            canvas.drawLine(px, py-radius, px, py-radius+10, markerPaint);  

            canvas.save();
            canvas.translate(0, textHeight);  

            if (i%6 == 0) {
                String dirString = "";
                switch (i) {
                    case (0) : {
                        dirString = northString;
                        int arrowY = 2*textHeight;
                        canvas.drawLine(px, arrowY, px-5, 3*textHeight, markerPaint);
                        canvas.drawLine(px, arrowY, px+5, 3*textHeight, markerPaint);
                        break;
                    }  

                    case (6) : dirString = eastString; break;
                    case (12) : dirString = southString; break;
                    case (18) : dirString = westString; break;
                }  

                canvas.drawText(dirString, cardinalX, cardinalY, textPaint);
            }  

            else if (i%3 == 0) {
                String angle = String.valueOf(i*15);
                float angleTextWidth = textPaint.measureText(angle);  

                int angleTextX = (int)(px-angleTextWidth/2);
                int angleTextY = py-radius+textHeight;
                canvas.drawText(angle, angleTextX, angleTextY, textPaint);
            }  

            canvas.restore();  

            canvas.rotate(15, px, py);
        }
        canvas.restore();
    }  

    @Override
    public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
        super.dispatchPopulateAccessibilityEvent(event);  

        if (isShown()) {
            String bearingStr = String.valueOf(bearing);  

            event.getText().add(bearingStr);  

            return true;
        } else
            return false;
    }
}

这个类代码较多, 详解:

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/extra/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, android canvas
, int
, private
, context
, compass
, import
, paint
, views py
, #电子罗盘
, android中context详解
, android中的context
onMeasure
compass 罗盘信息、android compass、中国罗盘详解、罗盘详解、风水罗盘盘面详解,以便于您获取更多的相关知识。

时间: 2024-09-08 08:39:45

Android中的Compass(罗盘) 详解的相关文章

Android中Service(后台服务)详解

  这篇文章主要介绍了Android中Service(后台服务)详解,本文讲解了Service的概念.作用.生命周期.启动方式和代码实例等内容,需要的朋友可以参考下 1.概念: (1).Service可以说是一个在后台运行的Activity.它不是一个单独的进程,它只需要应用告诉它要在后台做什么就可以了. (2).它要是实现和用户的交互的话需要通过通知栏或者是通过发送广播,UI去接收显示. (3).它的应用十分广泛,尤其是在框架层,应用更多的是对系统服务的调用. 2.作用: (1).它用于处理一

Java中的instanceof关键字在Android中的用法实例详解_java

在下面介绍Android中如何使用instanceof关键字开发更方便时,先来温习一下java中instanceof的概念. instanceof大部分的概念是这样定义的:instanceof是Java的一个二元操作符,和==,>,<是同一类东西.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据.举个栗子: String s = "I AM an Object!"; boolean isObj

Android 中Manifest.xml文件详解

Android 中Manifest.xml文件详解 每一个Android项目都包含一个清单(Manifest)文件--AndroidManifest.xml,它存储在项目层次中的最底层.清单可以定义应用程序及其组件的结构和元数据. 它包含了组成应用程序的每一个组件(活动.服务.内容提供器和广播接收器)的节点,并使用Intent过滤器和权限来确定这些组件之间以及这些组件和其他应用程序是如何交互的. 它还提供了各种属性来详细地说明应用程序的元数据(如它的图标或者主题)以及额外的可用来进行安全设置和单

Android中图片压缩方案详解及源码下载

Android中图片压缩方案详解及源码下载 图片的展示可以说在我们任何一个应用中都避免不了,可是大量的图片就会出现很多的问题,比如加载大图片或者多图时的OOM问题,可以移步到Android高效加载大图及多图避免程序OOM.还有一个问题就是图片的上传下载问题,往往我们都喜欢图片既清楚又占的内存小,也就是尽可能少的耗费我们的流量,这就是我今天所要讲述的问题:图片的压缩方案的详解. 1.质量压缩法 设置bitmap options属性,降低图片的质量,像素不会减少 第一个参数为需要压缩的bitmap图

Android 中 onSaveInstanceState()使用方法详解

Android 中 onSaveInstanceState()使用方法详解 覆盖onSaveInstanceState方法,并在onCreate中检测savedInstanceState和获取保存的值 @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("currentposition", videoView.getCurrentPosition()); super.onSave

Android 中 ActivityLifecycleCallbacks的实例详解

Android 中 ActivityLifecycleCallbacks的实例详解 以上就是使用ActivityLifecycleCallbacks的实例,代码注释写的很清楚大家可以参考下, MyApplication如下: package com.cc; import java.util.LinkedList; import android.app.Activity; import android.app.Application; import android.os.Bundle; /** *

Android 中ContentProvider的实例详解

Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据.这也是跨应用 共享数据的唯一方式.在Android系统中,没有一个公共的内存区域,供多个应用共享存储数据: * Android 提供了一些主要数据类型的ContentProvider ,比如:音频.视频.图片和私人通讯录等: 在android.provider 包下面找到一些android提供的C

Android 中Banner的使用详解

首先倒入一个依赖: compile 'com.youth.banner:banner:1.4.9' 添加的权限: <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 布局文件: <com.youth.banner.B

Android中ContentProvider和ContentResolver详解

Android中ContentProvider和ContentResolver详解 在Android中,我们的应用有的时候需要对外提供数据接口,可以有如下几种方法: 1)AIDL 2)Broadcast 3)ContentProvider. 使用AIDL需要我们编写AIDL接口以及实现,而且对方也要有相应的接口描述,有点麻烦:使用Broadcast,我们不需要任何接口描述,只要协议文档就可以了,但是有点不好就是,这种方式不直接而且是异步的:使用ContentProvider我们不需要接口描述,只