`
jayghost
  • 浏览: 440121 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

创建指南针View的例子(1)

阅读更多

在接下来的例子里,你将通过扩展View类创建一个指南针View。它使用传统的指南针上升箭头来指示方向。当完成时,应该和图4-3看起来一样。

 

指南针是一个UI控件的例子,它需要完全不同的视觉显示,不同于SDK工具箱中的TextViewButton,让我们从无到有使它成为一个出色的控件。

 

在第10章,你将使用这个指南针View和设备内建的重力加速计来显示用户当前的方向。在11章中,你将学习更高级的Canvas绘制技巧来戏剧性地改进它的外观。

  

 

  4-3

 

1. 创建一个新的指南针工程,包含指南针View和拥有它的Activity。现在创建CompassView类来扩展View。创建构造函数来运行View可以在代码中实例化,或者通过资源layout的膨胀。添加一个新的initCompassView方法来初始化控件,并在每个构造函数中调用它。

 

package com.paad.compass;

 

import android.content.Context;

import android.graphics.*;

import android.graphics.drawable.*;

import android.view.*;

import android.util.AttributeSet;

import android.content.res.Resources;

 

public class CompassView extends View {

public CompassView(Context context) {

super(context);

initCompassView();

}

 

public CompassView(Context context, AttributeSet attrs) {

super(context, attrs);

initCompassView();

}

 

public CompassView(Context context, AttributeSet ats, int defaultStyle) {

super(context, ats, defaultStyle);

initCompassView();

}

 

protected void initCompassView() {

setFocusable(true);

}

}

 

2. 指南针控件应该总是一个圆的方式占据画布允许的尽可能多的空间。重写onMeasure方法来计算最小的边,使用setMeasuredDimension来设置高度和高度值。

 

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// The compass is a circle that fills as much space as possible.

// Set the measured dimensions by figuring out the shortest boundary,

// height or width.

int measuredWidth = measure(widthMeasureSpec);

int measuredHeight = measure(heightMeasureSpec);

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

setMeasuredDimension(d, d);

}

 

private int measure(int measureSpec) {

int result = 0;

// Decode the measurement specifications.

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

if (specMode == MeasureSpec.UNSPECIFIED)

{

// Return a default size of 200 if no bounds are specified.

result = 200;

}

else

{

// As you want to fill the available space

// always return the full available bounds.

result = specSize;

}

return result;

}

 

3. 创建两个你将在绘制指南针时用到的资源文件:颜色和字符串。

3.1. 创建文本字符串资源 /res/values/strings.xml.

 

<?xml version=1.0 encoding=utf-8?>

<resources>

<string name=app_name>Compass</string>

<string name=cardinal_north>N</string>

<string name=cardinal_east>E</string>

<string name=cardinal_south>S</string>

<string name=cardinal_west>W</string>

</resources>

 

3.2. 创建颜色资源 /res/values/colors.xml.

 

<?xml version=1.0 encoding=utf-8?>

<resources>

<color name=background_color>#F555</color>

<color name=marker_color>#AFFF</color>

<color name=text_color>#AFFF</color>

</resources>

 

4. 现在回到CompassView类中。创建一个用来显示方向的属性并为它创建getset方法。

 

private float bearing;

public void setBearing(float _bearing) {

bearing = _bearing;

}

 

public float getBearing() {

return bearing;

}

 

5. 接下来,返回到initCompassView方法中,获取第3步中创建的资源的引用。以类作用域的方法存储字符串值和由颜色值创建的Paint对象。你将在下一步中用这些对象来绘制指南针。

 

private Paint markerPaint;

private Paint textPaint;

private Paint circlePaint;

private String northString;

private String eastString;

private String southString;

private String westString;

private int textHeight;

 

protected void initCompassView() {

setFocusable(true);

 

circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

circlePaint.setColor(R.color. background_color);

circlePaint.setStrokeWidth(1);

circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);

 

Resources r = this.getResources();

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));

}

 

6. 最后一步就是用第5步中创建的字符串和Paint对象来绘制指南针。接下来的代码片段只给出了有限的提示。你可以在第11章找到更多关于如何在Canvas上绘制和使用高级的Paint效果的细节。

 

6.1. 首先重写onDraw方法。

 

@Override

protected void onDraw(Canvas canvas) {

 

6.2. 找到控件的中心,存储最小边的长度作为指南针的半径。

 

int px = getMeasuredWidth() / 2;

int py = getMeasuredHeight() /2 ;

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

 

6.3.  使用drawCircle方法绘制外边框,背景的颜色使用第5步中创建的circlePaint对象。

 

// Draw the background

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

 

6.4. 指南针通过旋转面板来显示当前的指向,所以当前的方向总是在设备的顶端。为了达到这个效果,沿着当前指向的相反方向来旋转画布。

 

// Rotate our perspective so that the top is

// facing the current bearing.

canvas.save();

canvas.rotate(-bearing, px, py);

 

6.5. 现在剩下来的就是绘制表盘。旋转画布一周,每隔15°绘制一个标记,每隔45°绘制一个方向字符串。

 

int textWidth = (int)textPaint.measureText(W);

int cardinalX = px-textWidth/2;

int cardinalY = py-radius+textHeight;

 

// Draw the marker every 15 degrees and text every 45.

for (int i = 0; i < 24; i++)

{

// Draw a marker.

canvas.drawLine(px, py-radius, px, py-radius+10, markerPaint);

canvas.save();

canvas.translate(0, textHeight);

 

// Draw the cardinal points

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)

{

// Draw the text every alternate 45deg

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();

 

分享到:
评论

相关推荐

    Android-ChaosCompass自定义View实现小米指南针和时钟

    总结来说,"Android-ChaosCompass自定义View实现小米指南针和时钟"项目涵盖了Android自定义View的创建、传感器数据的获取与处理、动画效果的实现等多个重要知识点。通过学习这个项目,开发者可以深入理解Android系统...

    android studio指南针

    在Android开发领域,创建一个指南针应用是一项基础但实用的任务,尤其对于初学者而言,它可以帮助理解Android Studio的环境以及传感器API的运用。本指南针应用的开发将围绕以下几个核心知识点展开: 1. **Android ...

    安卓studio写的指南针

    - 创建一个自定义View,包含指南针的背景和指针图像。使用`onDraw()`方法,每次更新方向时重绘View,以反映最新的朝向。 7. **优化与注意事项**: - 为了避免频繁的重绘导致性能问题,可以使用`...

    指南针安卓端源码.zip

    4. **UI元素**:在布局文件中,可能包含一个ImageView或自定义View来显示指南针指针,以及TextView显示当前的度数。使用Animation或者ObjectAnimator可以实现指针的动态旋转效果,使其跟随方向变化而转动。 5. **...

    Android实现指南针

    5. **更新UI**:将计算出的`azimuth`应用到指南针视图,例如一个ImageView或自定义View,让指针旋转到对应的角度。 6. **清理资源**:在`onPause()`方法中,记得取消注册传感器监听器,避免浪费资源。 ```java @...

    自己写的指南针代码

    UI部分,开发者通常会创建一个自定义的View,比如CompassView,其中包含一个可以旋转的ImageView作为指南针指针。在每次角度更新时,通过旋转ImageView来更新指南针的显示。这可能涉及到动画效果的实现,如...

    基于Android Studio的指南针开发

    确保在创建项目时选择合适的API级别,因为指南针功能可能需要特定版本以上的Android系统支持。 接下来,我们需要添加必要的权限。在AndroidManifest.xml文件中,添加以下权限,以允许访问设备的传感器: ```xml ...

    compass(指南针)仪表图形控件

    "compass(指南针)仪表图形控件"是一种专门用于创建直观且吸引人的交互式UI组件的工具,尤其适用于导航、定位或者监控系统中。这个控件提供了一个模拟真实世界指南针的视觉效果,使用户能够轻松理解并操作应用程序...

    Android代码-一款3D 的安卓自定义view 指南针

    首先,创建一个3D的指南针View,我们需要理解Android的图形渲染机制。在Android中,我们通常使用`Canvas`来绘制2D图形,而要实现3D效果,就需要利用`Matrix`矩阵变换以及对`Paint`属性的精细控制。这个指南针可能...

    安卓自定义指南针

    集成指南针功能的第一步是创建一个新的布局文件,包含一个可以旋转的ImageView或自定义View,代表指南针的指针。通常,我们会使用一个ImageView,设置其背景为指向北方的指南针图片,并通过设置其旋转动画来模拟指南...

    温度计 风向 指南针 自定义View的高度结合 适用于不同分辨率的手机

    标题提到的“温度计 风向 指南针 自定义View的高度结合”是一种将多个功能集成到一个自定义视图中的设计,适用于各种分辨率的手机。这种设计允许开发者在一个界面中同时展示实时的温度、湿度和风向信息,方便用户...

    Android参考源码-指南针定位源码.zip

    1. **传感器(Sensor)使用**:在Android中,指南针功能主要依赖于加速度计(Accelerometer)和磁力计(Magnetometer)这两个传感器。它们结合使用可以计算出设备的欧拉角,进而确定设备的朝向。 2. **...

    指南针安卓端源码

    【指南针安卓端源码】是一个面向Android平台的软件开发项目,主要功能是实现一个能够指示方向的指南针应用。这个源码对于学习Android开发,尤其是对传感器运用和地图导航有兴趣的开发者来说,是一个很好的学习资源。...

    Android 4.0下指南针开发源码,可在Nexus 4上完美运行

    - 显示指南针界面通常有两种方式:一是使用OpenGL ES绘制,二是创建自定义View。OpenGL ES可以实现更流畅的3D效果,但自定义View则相对简单,适用于简单的2D显示。在这个项目中,可能是使用自定义View来更新指南针...

    android 指南针实现源码

    1. **传感器(Sensors)**:Android指南针的核心是地磁传感器(Magnetic Field Sensor),它能够检测设备周围的磁场强度,提供X、Y、Z三个轴上的数据。另一个重要传感器是陀螺仪(Gyroscope),用于检测设备的旋转运动。...

    android指南针源码

    同时,为了保持指南针的流畅性,通常会使用`postInvalidate()`来异步刷新View。 5. **优化性能**:为了避免过度绘制和无效的计算,我们还需要在`onPause()`和`onStop()`中注销传感器监听,以及合理地处理传感器数据...

    android平台传感器,指南针程序源码

    此外,还会有一个自定义的View类,用于绘制指南针盘面。这个View需要重写onDraw()方法,根据计算出的方向角度更新指针的位置。 指南针程序的UI设计也是关键。一个好的指南针界面应该直观易读,同时具备良好的用户...

    android指南针

    4. **绘制指南针指针**:在Android中,可以使用View或者ImageView作为指南针的指针,并通过设置其旋转角度来模拟指南针的行为。在得到偏航角后,可以通过`setRotation()`方法更新指针的旋转角度。 5. **处理屏幕...

    指南针定位

    其次,为了显示指南针界面,我们通常会创建一个自定义的View,例如继承自`View`或`SurfaceView`。在这个自定义View中,我们可以绘制一个圆形的指南针盘面,用箭头指示当前的方向。利用Android的绘图API,如`Canvas`...

    Android编写的指南针

    6. **UI更新**: 计算出的角度需要实时更新到用户界面上,这可能涉及到一个旋转的ImageView或者自定义View,通过动画或者canvas画布来实现指南针指针的旋转效果。 7. **权限申请**: Android应用在访问传感器数据时...

Global site tag (gtag.js) - Google Analytics