浏览 10164 次
锁定老帖子 主题:android自己写的类似刻度尺的东西。
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-08-24
最后修改:2011-08-29
刚学android不久,因为公司项目要求,写了个类似刻度尺的东西,拿出来献丑,希望大家给点意见。 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> 附件是运行效果截图。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-08-25
求源码。。。。
|
|
返回顶楼 | |
发表时间:2011-08-25
zhaoxuyang6 写道 求源码。。。。
源码已经全部贴出来了啊。 |
|
返回顶楼 | |
发表时间:2011-08-25
最后修改:2011-08-25
zhaoxuyang6 写道
求源码。。。。
Arithmetic类的源码如下: package com.hyx.suiyipaint; import java.math.BigDecimal; public class Arithmetic { /** * 提供精确的加法运算。 * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static float add(float v1, float v2){ BigDecimal b1 = new BigDecimal(Float.toString(v1)); BigDecimal b2 = new BigDecimal(Float.toString(v2)); return b1.add(b2).floatValue(); } /** * 提供精确的减法运算。 * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static float sub(float v1, float v2){ BigDecimal b1 = new BigDecimal(Float.toString(v1)); BigDecimal b2 = new BigDecimal(Float.toString(v2)); return b1.subtract(b2).floatValue(); } /** * 提供精确的乘法运算。 * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static float mul(float v1, float v2){ BigDecimal b1 = new BigDecimal(Float.toString(v1)); BigDecimal b2 = new BigDecimal(Float.toString(v2)); return b1.multiply(b2).floatValue(); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static float div(float v1, float v2, int scale){ if(scale<0){ scale = 0; } BigDecimal b1 = new BigDecimal(Float.toString(v1)); BigDecimal b2 = new BigDecimal(Float.toString(v2)); return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).floatValue(); } /** * 提供精确的小数位四舍五入处理。 * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static float round(float v, int scale){ if(scale<0){ scale = 0; } BigDecimal b = new BigDecimal(Float.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).floatValue(); } } |
|
返回顶楼 | |
发表时间:2011-08-25
最后修改:2011-08-25
zhaoxuyang6 写道 求源码。。。。
你个没骨气的家伙,好好跟哥学学! 哥最看不起求源码的人了! 看不起! 看不起! LZ,求工程。。。。 |
|
返回顶楼 | |
发表时间:2011-08-25
楼主给出项目图片就行了
|
|
返回顶楼 | |
发表时间:2011-08-26
其实代码很简单,写不难懂,我把用到的图片给大家附上哈。
|
|
返回顶楼 | |
发表时间:2011-09-20
楼主只需要写出大致的思路就行了,没有必要贴源码,看的人也累。
|
|
返回顶楼 | |
发表时间:2012-01-14
仍然不怕死的求完整包,刚学几天,新手也需要学习封装类的思想
|
|
返回顶楼 | |
发表时间:2012-06-07
哈哈求图片
|
|
返回顶楼 | |