android自己寫的類似刻度尺的東西 – Android移動開發技術文章_手機開發 Android移動開發教學課程

剛學android不久,因為公司項目要求,寫瞭個類似刻度尺的東西,拿出來獻醜,希望大傢給點意見。

先上代碼,註:KeduView中的浮點數計算我沒處理(因為精度問題,浮點數直接計算出來的結果可能不對)。StaffView中的浮點數計算我進行瞭處理,我在Arithmetic中封裝瞭加減乘除方法:
Java代碼 
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.p(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> 
 附件是運行效果截圖。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *