由于项目中有数据需要通过仪表图进行数据的展示,所以在此进行一下总结,数据仪表图的实现方法本人用过的有3种,分别进行一下总结。
1.通过加载webview来显示仪表图
这种方式类似于使用网页的形式,由于HTML中含有许多仪表图的显示,而且样式也比较好看,原理主要是通过使用js在HTML页面进行仪表图的绘制,通过安卓的相关代码将仪表刻度数据传给webView来进行显示,但是要求对HTML及js有相关了解,便于更改仪表图的样式,这种方式我找了相关的HTML仪表图的代码,进行了简单的测试,由于和我的项目中不太相符,就弃用了这种方式。
2.通过画布进行绘制
这是一开始使用的方式,需要两张图片,一张仪表盘,一张指针
这是单独定义的仪表图类
public class DialView extends SurfaceView implements Callback{
private SurfaceHolder holder;
private Paint paint;
private Canvas canvas;
private Bitmap bigDialBmp,bigPointerBmp; //仪表图和指针的定义
private int bigDialX,bigDialY,bigPointerX,bigPointerY;
private Rect bgRect;
public int bigDialDegrees;
private int drawable;
public int getDrawable() {
return drawable;
}
public void setDrawable(int drawable) {
this.drawable = drawable;
}
public DialView(Context context, int bigDialDegrees) { //构造方法 传入度数
super(context);
this.bigDialDegrees = bigDialDegrees;
}
public DialView(Context context, AttributeSet attrs) {
super(context, attrs);
holder=getHolder();
holder.addCallback(this);
paint = new Paint();
paint.setAntiAlias(true);
// paint.setColor(Color.BLACK);
paint.setColor(Color.argb(255, 207, 60, 11));
paint.setTextSize(22);
setFocusable(true);
setFocusableInTouchMode(true);
}
public void myDraw(){
try {
canvas=holder.lockCanvas(bgRect);
canvas.drawColor(Color.WHITE);
drawBigDial();
} catch (Exception e) {
e.printStackTrace();
}finally{
holder.unlockCanvasAndPost(canvas);
}
}
public void drawBigDial(){ //对于这块绘制内容,需要严格的计算仪表图和指针的一些距离,指定指针绕着某个点进行旋转,而且指针绕自身旋转的中心点也要计算好
canvas.drawBitmap(bigDialBmp, bigDialX, bigDialY, paint);
canvas.save();
float rx=bigPointerX;
float ry=bigPointerY;
canvas.rotate(bigDialDegrees+90,rx+bigPointerBmp.getWidth()/2, ry+10);
//System.out.println("x"+rx+"y"+ry);
//paint.setAlpha(127);
canvas.drawBitmap(bigPointerBmp,rx,ry,paint);
canvas.restore();
}
public void surfaceCreated(SurfaceHolder holder) {
bigDialBmp = BitmapFactory.decodeResource(getResources(), drawable);
bigPointerBmp = BitmapFactory.decodeResource(getResources(), R.drawable.point);
bigDialX =20;
bigDialY =50;
bigPointerX = 20/2+(bigDialBmp.getWidth()-8)/2-bigPointerBmp.getWidth()/2+10;
bigPointerY = 50+bigDialBmp.getHeight()-10;
myDraw();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public int getBigDialDegrees() {
return bigDialDegrees;
}
public void setBigDialDegrees(int bigDialDegrees) {
this.bigDialDegrees = bigDialDegrees;
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
}
在需要用到的地方进行定义
public DialView dialimage;
dialimage=(DialView)findViewById(R.id.dialView);
d.dialimage.setBigDialDegrees(度数); //这里设置度数
d.dialimage.setDrawable(仪表图图片);//这里可以设置不同的仪表图背景
xml文件的配置
<com.jxj.view.DialView //类包括包名的全称
android:id="@+id/dialView"
android:layout_width="match_parent"
android:layout_height="110dip"
android:layout_gravity="center"
/>
这种方法的好处是可以定义半个圆,缺点是对尺寸的要求较高,需要认真计算,而且指针有时会出现边缘锯齿化,效果图如下
3.使用RelativeLayout让仪表图和指针图完全重叠,然后让指针图绕中心旋转
xml文件的配置
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="1dp"
android:background="@color/white"
>
<ImageView
android:id="@+id/dial_bg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
/>
<ImageView
android:id="@+id/dial_point"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@drawable/dial_point"
/>
代码比较简单
public ImageView dialbg;
public ImageView dialpoint;
RotateAnimation animation = new RotateAnimation(度数,
healthData[position], Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(1000);
animation.setFillAfter(true);
dialpoint.startAnimation(animation);
dialbg.setImageResource(仪表图图片);
这种方式唯一的缺点就是整个仪表图的下方会留出和上面仪表图一样大小的空白,当然这块空白可以自由添加其他内容,比如数据显示或说明等
效果图如下:
关于仪表图的实现,网上的资源还不是很丰富,希望进行分享和讨论,有仪表图相关的更成熟的实现代码。