`
永9久
  • 浏览: 12379 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

android自己写的类似刻度尺的东西。

阅读更多

刚学android不久,因为公司项目要求,写了个类似刻度尺的东西,拿出来献丑,希望大家给点意见。

先上代码,注:KeduView中的浮点数计算我没处理(因为精度问题,浮点数直接计算出来的结果可能不对)。StaffView中的浮点数计算我进行了处理,我在Arithmetic中封装了加减乘除方法:

package com.hyx.suiyipaint;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class KeduActivity extends Activity {
	
	private ImageView kedu_tiao;
	private LinearLayout kedu_linear;
	private LinearLayout staff_linear;
	
	private KeduView kedu;
	private StaffView staff;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.kedu);
		
		kedu_linear = (LinearLayout)findViewById(R.id.kedu_linear);
		kedu = new KeduView(this, 0f, 0.1f);
		kedu_linear.addView(kedu);
		staff_linear = (LinearLayout)findViewById(R.id.staff_linear);
		staff = new StaffView(this, 7.5f, 0.5f, "cm");
		staff_linear.addView(staff);
		
		kedu_tiao = (ImageView)findViewById(R.id.kedu_tiao);
		kedu_tiao.setOnTouchListener(keduListener);
		
	}
	
	private ImageView.OnTouchListener keduListener = new ImageView.OnTouchListener(){
		private float initx = 0;
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch(event.getAction()){
				case MotionEvent.ACTION_DOWN:
					initx = event.getX();
					break;
				case MotionEvent.ACTION_MOVE:
					float lastx = event.getX();
					if(lastx > initx + 5){
						kedu.draw(1);
						initx = lastx;
					}else if(lastx < initx -5){
						kedu.draw(-1);
						initx = lastx;
					}
					break;
			}
			return true;
		}
	};
	
	class KeduView extends SurfaceView implements SurfaceHolder.Callback, Runnable{
		
		private SurfaceHolder mSurfaceHolder = null;  
		private Canvas canvas;
		//画布背景
		private Bitmap background;
		//刻度游标
		private Bitmap pointer;

		//总刻度数
		private static final int KEDU_COUNT = 25;
		//刻度最小值
		private float init_min;
		//每个刻度的单位值
		private float interval;

		public KeduView(Context context, float init_min, float interval) {
			super(context);
			mSurfaceHolder = this.getHolder();  
			mSurfaceHolder.addCallback(this);  
			this.setFocusable(true);
			background = BitmapFactory.decodeResource(getResources(), R.drawable.kedu_bg);
			pointer = BitmapFactory.decodeResource(getResources(), R.drawable.kedu_pointer);
			
			this.init_min = init_min;
			this.interval = interval;
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
			
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			new Thread(this).start();
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			
		}
		
		@Override
		public void run() {
			draw(0);
		}
		//每次X轴移动的像素
		private static final int MOVE = 10;
		//游标在最左边时X轴的位置
		private static final int INIT_POINTER_LEFT = 20;
		//游标在最右边时X轴的位置
		private static final int INIT_POINTER_RIGHT = 270;
		//游标顶端Y轴的位置
		private static final int INIT_POINTER_TOP = 36;
		//底下刻度数字最左边的X轴位置
		private static final int INIT_NUM_X = 18;
		//结果的X轴位置
		private static final int RESULT_X = 36;
		//结果的Y轴位置
		private static final int RESULT_Y = 25;
		//结果的字体大小
		private static final int RESULT_SIZE = 24;
		//游标X轴的位置
		private int POINTER_X = INIT_POINTER_LEFT;
		//底下刻度数字X轴位置
		private int NUM_X = INIT_NUM_X;
		//底下刻度数字的Y轴位置
		private int NUM_Y = 85;
		//结果
		private float result = 0;

		/**
		 * @param direction 方向,-1向左,1向右,0不动
		 */
		public void draw(int direction){
			//获取画布
			canvas = mSurfaceHolder.lockCanvas();
			if (mSurfaceHolder == null || canvas == null) {  
				return;  
			}
			canvas.drawColor(Color.WHITE);
			Paint paint = new Paint();  
			paint.setAntiAlias(true);  
			paint.setColor(Color.GRAY);
			canvas.drawBitmap(background, new Matrix(), paint);
			
			switch(direction){
				case -1:
					POINTER_X -= MOVE;
					result -= interval;
					if(result <= 0){
						result  = init_min;
						POINTER_X = INIT_POINTER_LEFT;
					}else{
						if(POINTER_X < INIT_POINTER_LEFT){
							POINTER_X = INIT_POINTER_RIGHT;
							result = init_min;
							init_min -= KEDU_COUNT * interval;
						}
					}
					break;
				case 1:
					POINTER_X += MOVE;
					result += interval;
					if(POINTER_X > INIT_POINTER_RIGHT){
						POINTER_X = INIT_POINTER_LEFT;
						init_min += KEDU_COUNT * interval;
						result = init_min;
					}
					break;
			}
			canvas.drawBitmap(pointer, POINTER_X, INIT_POINTER_TOP, paint);
			
			for(int i=0; i<6; i++){
				if(i == 0){
					NUM_X = INIT_NUM_X;
				}
				canvas.drawText(Float.toString(i * 5f * interval + init_min), NUM_X, NUM_Y, paint);
				NUM_X += 50;
			}
			
			paint.setColor(Color.BLACK);
			paint.setTextSize(RESULT_SIZE);
			canvas.drawText(Float.toString(result), RESULT_X, RESULT_Y, paint);
			//解锁画布,提交画好的图像  
			mSurfaceHolder.unlockCanvasAndPost(canvas);  
		}
	}

	class StaffView extends SurfaceView implements SurfaceHolder.Callback, Runnable{

		private SurfaceHolder mSurfaceHolder = null;  
		private Canvas canvas;
		private Paint paint;
		//画布背景
		private Bitmap background;
		//刻度
		private Bitmap staff;
		//刻度游标
		private Bitmap pointer;
		//初始值
		private float initValue;
		//刻度单位最小值
		private float interval;
		//单位
		private String unit;
		//是否初始
		private boolean isInit = true;
		
		public StaffView(Context context, float initValue, float interval, String unit) {
			super(context);
			mSurfaceHolder = this.getHolder();  
			mSurfaceHolder.addCallback(this);  
			
			paint = new Paint();
			
			this.setFocusable(true);
			background = BitmapFactory.decodeResource(getResources(), R.drawable.staff_bg);
			staff = BitmapFactory.decodeResource(getResources(), R.drawable.staff0);
			pointer = BitmapFactory.decodeResource(getResources(), R.drawable.kedu_pointer);
  
			this.initValue = initValue;
			this.interval = interval;
			this.unit = unit;
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
			
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			new Thread(this).start();
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			
		}

		@Override
		public void run() {
			draw(0);
		}
		
		private int move = 10;	//每次移动的距离
		private int initBx = 77;	//图片上X坐标
		private int by = 0;	//图片上Y坐标
		private int bw = 258;	//图片宽度
		private int bh = 31;	//图片高度
		private int sx = 18;	//画布X坐标
		private int sy = 36;	//画布Y坐标
		private int jiange = 51; //大刻度之间距离
		private int num_left = 33;	//最左边数字到左边的距离
		private int RESULT_X = 36;	//结果的X轴位置
		private int RESULT_Y = 25;	//结果的Y轴位置
		private int RESULT_SIZE = 24;	//结果的字体大小
		
		private float result = 0;
		/**
		 * @param direction 方向,-1向左,1向右,0不动
		 */
		public void draw(int direction){
			//获取画布
			canvas = mSurfaceHolder.lockCanvas();
			if (mSurfaceHolder == null || canvas == null) {  
				return;  
			}
			canvas.drawColor(Color.WHITE);
			
			paint.setAntiAlias(true);  
			paint.setColor(Color.GRAY);
			
			canvas.drawBitmap(background, new Matrix(), paint);
			
			if(isInit){
				result = initValue;
			}else{
				switch(direction){
					case 1:
						result = Arithmetic.add(result, interval);
						break;
					case -1:
						result = Arithmetic.sub(result, interval);
						if(result < 0){
							result = 0;
						}
						break;
				}
			}
			initStaff();

			canvas.drawBitmap(pointer, 143, 36, paint);

			Paint reslutPaint = new Paint();
			reslutPaint.setColor(Color.BLACK);
			reslutPaint.setTextSize(RESULT_SIZE);
			canvas.drawText(Float.toString(result) + " " + unit, RESULT_X, RESULT_Y, reslutPaint);
			//解锁画布,提交画好的图像  
			mSurfaceHolder.unlockCanvasAndPost(canvas);  
		}
		
		private void initStaff(){
			int bx = initBx;
			int num_x = num_left;
			int mod = 0;
			int midd = 2;
			if(result != 0){
				mod = (int)(Arithmetic.div(result, interval, 1) % 5);
				bx += mod * move;
			}
			if(mod >= 3){
				midd = 1;
				num_x += (5 - mod) * move;
			}else{
				num_x -= mod * move;
			}
			float text = 0;
			for(int i=0; i<5; i++){
				if(i < midd){
					text = result - mod * interval - (midd - i) * 5 * interval;
				}else if(i == midd){
					text = result - mod * interval;
				}else{
					text += 5 * interval;
				}
				text = Arithmetic.round(text, 1);
				if(text >= 0){
					canvas.drawText(Float.toString(text), num_x, 85, paint);
				}
				num_x += jiange;
			}

			//要绘制的图片矩形区域设置
			Rect src = new Rect();
			src.left = bx;
			src.top = by;
			src.right = bx + bw;
			src.bottom = bh;
			
			//要绘制的画布矩形区域设置
			Rect dst = new Rect();
			dst.left = sx;
			dst.top = sy;
			dst.right = sx + bw;
			dst.bottom = sy + bh;
			canvas.drawBitmap(staff, src, dst, paint);
		}
		
		private float initx = 0;
		@Override
		public boolean onTouchEvent(MotionEvent event) {
			switch(event.getAction()){
				case MotionEvent.ACTION_DOWN:
					initx = event.getX();
					break;
				case MotionEvent.ACTION_MOVE:
					float lastx = event.getX();
					if(lastx > initx + 5){
						isInit = false;
						draw(-1);
						initx = lastx;
					}else if(lastx < initx -5){
						isInit = false;
						draw(1);
						initx = lastx;
					}
					break;
			}
				return true;
		}
		
		public float getResult(){
			return result;
		}
	}
	
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
			staff.isInit = false;
			staff.draw(-1);
			return true;
		}if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
			staff.isInit = false;
			staff.draw(1);
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}

 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:gravity="center"
  android:background="#fff">
    <LinearLayout 
    	android:id="@+id/kedu_linear" 
    	android:layout_width="294dp" 
    	android:layout_height="101dp"/>
    <ImageView 
    	android:layout_height="wrap_content"  
    	android:layout_width="wrap_content"
    	android:id="@+id/kedu_tiao" 
    	android:src="@drawable/kedu_wheel_01"
    	android:layout_margin="20dp"/>
    <LinearLayout 
    	android:id="@+id/staff_linear" 
    	android:layout_width="294dp" 
    	android:layout_height="101dp"/>
    
</LinearLayout>

 附件是运行效果截图。

  • 大小: 14 KB
分享到:
评论
2 楼 hcq2659888 2014-05-15  
没有完整的布局文件啊楼主
1 楼 hcq2659888 2014-05-15  
楼主,能不能把刻度尺的工程源码给我下啊,谢谢了!156089727@qq.com

相关推荐

    Android 竖直刻度尺效果

    在Android开发中,创建一个竖直刻度尺效果通常是用于展示数据或指示度量值的可视化组件。这种效果可以应用于各种场景,如健康应用显示心率范围、金融应用表示股票指数,或者是测量工具类应用等。本文将详细介绍如何...

    android 刻度尺的实现

    在Android开发中,实现一个刻度尺功能是一个常见的需求,特别是在一些测量类或者设置界面的应用中。刻度尺的设计通常包含一个固定的中心线,以及可滑动的刻度标记。以下我们将详细探讨如何在Android中实现这样的功能...

    Android-自定义水平刻度尺和圆形钟表刻度

    在Android开发中,有时我们需要创建独特且具有交互性的UI组件,比如自定义的水平刻度尺和圆形钟表刻度。这些控件可以用于时间显示、进度指示或者数据选择等场景,提供用户友好的交互体验。本文将详细介绍如何在...

    Android-自定义时间刻度尺(随着手指自行缩放)多种显示模式

    "Android-自定义时间刻度尺(随着手指自行缩放)多种显示模式"是一个专注于时间展示的自定义控件,它允许用户根据手势操作自由缩放时间刻度,提供了多种不同的显示模式。这种控件在日程管理、时钟应用或者任何需要直观...

    Android可滑动刻度尺

    "Android可滑动刻度尺"是一个自定义视图,它允许用户通过滑动来选择一个数值范围,通常用于设置音量、亮度或者任何需要精细调整的参数。下面我们将详细探讨这个刻度尺的实现方式和相关知识点。 首先,刻度尺分为两...

    android 自定义刻度尺工具

    本项目名为"android 自定义刻度尺工具",显然它是一个专为Android平台设计的可自定义、可移动的刻度尺控件。这个控件的实现涉及到Android图形绘制、触摸事件处理以及自定义View的相关知识。 首先,我们来看刻度尺的...

    android计步器刻度尺源码.rar

    《Android计步器与刻度尺源码解析》 Android计步器与刻度尺源码是Android开发中涉及健康监测和图形界面设计的重要实践案例。这个压缩包包含的源码,提供了实现计步器功能以及刻度尺显示的详细代码,对于Android...

    android 刻度尺,刻度不动,滑动选择

    在Android开发中,创建一个刻度尺控件可以让用户通过滑动来选择特定值,这种交互方式常见于音量调节、进度控制等场景。"android 刻度尺,刻度不动,滑动选择"这个话题涉及到自定义视图、触摸事件处理以及动画效果的...

    android 可滑动的刻度尺

    android 可滑动的刻度尺,核心方法在ondraw和onTouchEvent方法中

    Android 简单刻度尺.zip

    【Android 简单刻度尺】是一款针对Android平台开发的简单刻度尺应用,它主要功能是提供一个可滑动的刻度尺界面,使用户能够方便地进行长度测量。刻度尺的设计使得指针在滑动后会自动对齐到最近的大刻度,增加了使用...

    Android-LoopScale循环滚动的刻度尺控件

    3. 动画效果:为了使滚动更加平滑,可以使用Android的动画框架,如ValueAnimator或ObjectAnimator,来实现刻度尺的平滑移动。这不仅可以提高用户体验,还可以在达到一端时自然过渡到另一端。 4. 数据绑定:...

    Android缩放平移的时间刻度尺

    "Android缩放平移的时间刻度尺"项目提供了一个可扩展的解决方案,帮助开发者实现类似功能。下面将详细阐述这个组件的关键知识点。 1. **自定义View**: 时间刻度尺本质上是一个自定义的Android View,通过继承自`...

    Android-TapeHencoder高度自定义刻度尺HenCoder仿写系列

    "Android-TapeHencoder高度自定义刻度尺HenCoder仿写系列"就是这样一个项目,它专注于实现一个高度可定制的刻度尺控件,灵感来源于HenCoder的教学系列。HenCoder是一个广受欢迎的Android开发学习资源,它提供了许多...

    WORD制作打印刻度尺

    ### WORD制作打印刻度尺详解 #### 一、引言 在日常生活中,刻度尺是必不可少的测量工具之一,特别是在设计、...无论是学生还是职场人士,都可以根据自己的需求来制作个性化的刻度尺,极大地提升了工作效率和便利性。

    Android可滑动的刻度尺

    本主题聚焦于“Android可滑动的刻度尺”这一控件,它为用户提供了一种直观的方式来选择或调整数值。刻度尺控件通常包含一个可滑动的指针,沿着标有刻度值的尺子移动,用户可以通过滑动来设定值。 刻度尺控件的设计...

    android刻度尺

    在Android平台上开发一款刻度尺应用,涉及到许多关键的技术点,包括用户界面设计、图形处理、传感器利用以及数据存储等。下面将详细讲解这些知识点。 首先,**用户界面设计**是刻度尺应用的核心部分。刻度尺界面需...

    javascript 时间刻度尺插件

    JavaScript时间刻度尺插件是一种用于可视化时间轴的工具,常用于数据展示、日程管理或图表绘制等场景。它能够帮助用户清晰地看到时间序列上的各个关键点,提高数据的可读性和交互性。在本文中,我们将深入探讨这个...

    Android自定义刻度尺精确到毫米

    本文将深入探讨如何在Android中创建一个自定义刻度尺,精度达到毫米级别,这对于需要精确测量的应用场景尤其有用。这个自定义刻度尺的示例适合初学者学习自定义View的基础知识,同时也为有经验的开发者提供了参考。 ...

    vue刻度尺组件

    这个名为"vue刻度尺组件"的项目,很可能包含了一个自定义的Vue组件,用于在界面上显示可定制的刻度尺。 刻度尺组件通常由以下几个关键部分组成: 1. **结构(Structure)**:组件的基本HTML结构,包括尺子的主体、...

    刻滑动刻度尺

    开发者可以查看项目的代码,学习如何实现滑动刻度尺并将其集成到自己的应用中。这个示例可能包括了滑动事件的处理、滑动刻度尺的自定义样式以及与其他UI元素的交互等内容。 总的来说,滑动刻度尺(UISlider)是iOS...

Global site tag (gtag.js) - Google Analytics