剛學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代碼
- <?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>
運行效果截圖。