13.1.4. 自定义的表盘控件

优质
小牛编辑
133浏览
2023-12-01

13.1.4.自定义的表盘控件

Rose是我们自定义的UI控件,它可以旋转,表示指南针的表盘。Android中的任何UI控件都是View的子类。Rose的主要部分是一个图片,这一来我们可以让它继承自ImageView类,在较高的层面上实现它,从而可以使用原有的方法实现装载并显示图片。

自定义一个UI控件,onDraw()算是最重要的方法之一,它负责控件的绘制与显示。在Rose这里,图片的绘制可由父类完成,我们需要做的就是添加自己的逻辑,使图片可以按圆心旋转一定的度数,以表示指南针的方位。

例 13.2. Rose.java

package com.marakana;

import android.content.Context;

import android.graphics.Canvas;

import android.widget.ImageView;

public class Rose extends ImageView { //

int direction = 0;

public Rose(Context context) {

super(context);

this.setImageResource(R.drawable.compassrose); //

}

// Called when component is to be drawn

@Override

public void onDraw(Canvas canvas) { //

int height = this.getHeight(); //

int width = this.getWidth();

canvas.rotate(direction, width / 2, height / 2); //

super.onDraw(canvas); //

}

// Called by Compass to update the orientation

public void setDirection(int direction) { //

this.direction = direction;

this.invalidate(); // request to be redrawn

}

}

  1. 我们的控件必须是View的子类。它大体就是一张图片,因此可以让它继承自ImageView,得以使用现有的功能。
  2. ImageView本身已有设置图片内容的方法,我们需要做的就是为它指明相应的图片。留意,compassrose.jpg文件在/res/drawable之下。
  3. onDraw()由LayoutManager负责调用,指示控件来绘制自己。它会传递过来一个Canvas对象,你可以在这里执行自定义的绘制操作。
  4. 已获得Canvas对象,可以计算自身的宽高。
  5. 简单地以中点为圆心,按度数旋转整个Canvas。
  6. 通知super将图片绘制到这个旋转了的Canvas上。到这里表盘就显示出来了。
  7. setDirection()由Compass负责调用,它会根据传感器中获得的数据调整Rose的方向。
  8. 对View调用invalidate(),就可以要求它重绘。也就是在稍后调用onDraw()。

到这里,指南针程序已经可用了。在设备横放时,表盘应大致指向北方。仿真器没有传感器的支持,因此这个程序只能在真机上运行。