歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android寫的類似刻度尺的東西

Android寫的類似刻度尺的東西

日期:2017/3/1 10:39:17   编辑:Linux編程

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

先上代碼,注:KeduView中的浮點數計算我沒處理(因為精度問題,浮點數直接計算出來的結果可能不對)。StaffView中的浮點數計算我進行了處理,我在Arithmetic中封裝了加減乘除方法:

  1. package com.hyx.suiyipaint;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Color;
  8. import android.graphics.Matrix;
  9. import android.graphics.Paint;
  10. import android.graphics.Rect;
  11. import android.os.Bundle;
  12. import android.view.KeyEvent;
  13. import android.view.MotionEvent;
  14. import android.view.SurfaceHolder;
  15. import android.view.SurfaceView;
  16. import android.view.View;
  17. import android.widget.ImageView;
  18. import android.widget.LinearLayout;
  19. public class KeduActivity extends Activity {
  20. private ImageView kedu_tiao;
  21. private LinearLayout kedu_linear;
  22. private LinearLayout staff_linear;
  23. private KeduView kedu;
  24. private StaffView staff;
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.kedu);
  29. kedu_linear = (LinearLayout)findViewById(R.id.kedu_linear);
  30. kedu = new KeduView(this, 0f, 0.1f);
  31. kedu_linear.addView(kedu);
  32. staff_linear = (LinearLayout)findViewById(R.id.staff_linear);
  33. staff = new StaffView(this, 7.5f, 0.5f, "cm");
  34. staff_linear.addView(staff);
  35. kedu_tiao = (ImageView)findViewById(R.id.kedu_tiao);
  36. kedu_tiao.setOnTouchListener(keduListener);
  37. }
  38. private ImageView.OnTouchListener keduListener = new ImageView.OnTouchListener(){
  39. private float initx = 0;
  40. @Override
  41. public boolean onTouch(View v, MotionEvent event) {
  42. switch(event.getAction()){
  43. case MotionEvent.ACTION_DOWN:
  44. initx = event.getX();
  45. break;
  46. case MotionEvent.ACTION_MOVE:
  47. float lastx = event.getX();
  48. if(lastx > initx + 5){
  49. kedu.draw(1);
  50. initx = lastx;
  51. }else if(lastx < initx -5){
  52. kedu.draw(-1);
  53. initx = lastx;
  54. }
  55. break;
  56. }
  57. return true;
  58. }
  59. };
  60. class KeduView extends SurfaceView implements SurfaceHolder.Callback, Runnable{
  61. private SurfaceHolder mSurfaceHolder = null;
  62. private Canvas canvas;
  63. //畫布背景
  64. private Bitmap background;
  65. //刻度游標
  66. private Bitmap pointer;
  67. //總刻度數
  68. private static final int KEDU_COUNT = 25;
  69. //刻度最小值
  70. private float init_min;
  71. //每個刻度的單位值
  72. private float interval;
  73. public KeduView(Context context, float init_min, float interval) {
  74. super(context);
  75. mSurfaceHolder = this.getHolder();
  76. mSurfaceHolder.addCallback(this);
  77. this.setFocusable(true);
  78. background = BitmapFactory.decodeResource(getResources(), R.drawable.kedu_bg);
  79. pointer = BitmapFactory.decodeResource(getResources(), R.drawable.kedu_pointer);
  80. this.init_min = init_min;
  81. this.interval = interval;
  82. }
  83. @Override
  84. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  85. }
  86. @Override
  87. public void surfaceCreated(SurfaceHolder holder) {
  88. new Thread(this).start();
  89. }
  90. @Override
  91. public void surfaceDestroyed(SurfaceHolder holder) {
  92. }
  93. @Override
  94. public void run() {
  95. draw(0);
  96. }
  97. //每次X軸移動的像素
  98. private static final int MOVE = 10;
  99. //游標在最左邊時X軸的位置
  100. private static final int INIT_POINTER_LEFT = 20;
  101. //游標在最右邊時X軸的位置
  102. private static final int INIT_POINTER_RIGHT = 270;
  103. //游標頂端Y軸的位置
  104. private static final int INIT_POINTER_TOP = 36;
  105. //底下刻度數字最左邊的X軸位置
  106. private static final int INIT_NUM_X = 18;
  107. //結果的X軸位置
  108. private static final int RESULT_X = 36;
  109. //結果的Y軸位置
  110. private static final int RESULT_Y = 25;
  111. //結果的字體大小
  112. private static final int RESULT_SIZE = 24;
  113. //游標X軸的位置
  114. private int POINTER_X = INIT_POINTER_LEFT;
  115. //底下刻度數字X軸位置
  116. private int NUM_X = INIT_NUM_X;
  117. //底下刻度數字的Y軸位置
  118. private int NUM_Y = 85;
  119. //結果
  120. private float result = 0;
  121. /**
  122. * @param direction 方向,-1向左,1向右,0不動
  123. */
  124. public void draw(int direction){
  125. //獲取畫布
  126. canvas = mSurfaceHolder.lockCanvas();
  127. if (mSurfaceHolder == null || canvas == null) {
  128. return;
  129. }
  130. canvas.drawColor(Color.WHITE);
  131. Paint paint = new Paint();
  132. paint.setAntiAlias(true);
  133. paint.setColor(Color.GRAY);
  134. canvas.drawBitmap(background, new Matrix(), paint);
  135. switch(direction){
  136. case -1:
  137. POINTER_X -= MOVE;
  138. result -= interval;
  139. if(result <= 0){
  140. result = init_min;
  141. POINTER_X = INIT_POINTER_LEFT;
  142. }else{
  143. if(POINTER_X < INIT_POINTER_LEFT){
  144. POINTER_X = INIT_POINTER_RIGHT;
  145. result = init_min;
  146. init_min -= KEDU_COUNT * interval;
  147. }
  148. }
  149. break;
  150. case 1:
  151. POINTER_X += MOVE;
  152. result += interval;
  153. if(POINTER_X > INIT_POINTER_RIGHT){
  154. POINTER_X = INIT_POINTER_LEFT;
  155. init_min += KEDU_COUNT * interval;
  156. result = init_min;
  157. }
  158. break;
  159. }
  160. canvas.drawBitmap(pointer, POINTER_X, INIT_POINTER_TOP, paint);
  161. for(int i=0; i<6; i++){
  162. if(i == 0){
  163. NUM_X = INIT_NUM_X;
  164. }
  165. canvas.drawText(Float.toString(i * 5f * interval + init_min), NUM_X, NUM_Y, paint);
  166. NUM_X += 50;
  167. }
  168. paint.setColor(Color.BLACK);
  169. paint.setTextSize(RESULT_SIZE);
  170. canvas.drawText(Float.toString(result), RESULT_X, RESULT_Y, paint);
  171. //解鎖畫布,提交畫好的圖像
  172. mSurfaceHolder.unlockCanvasAndPost(canvas);
  173. }
  174. }
  175. class StaffView extends SurfaceView implements SurfaceHolder.Callback, Runnable{
  176. private SurfaceHolder mSurfaceHolder = null;
  177. private Canvas canvas;
  178. private Paint paint;
  179. //畫布背景
  180. private Bitmap background;
  181. //刻度
  182. private Bitmap staff;
  183. //刻度游標
  184. private Bitmap pointer;
  185. //初始值
  186. private float initValue;
  187. //刻度單位最小值
  188. private float interval;
  189. //單位
  190. private String unit;
  191. //是否初始
  192. private boolean isInit = true;
  193. public StaffView(Context context, float initValue, float interval, String unit) {
  194. super(context);
  195. mSurfaceHolder = this.getHolder();
  196. mSurfaceHolder.addCallback(this);
  197. paint = new Paint();
  198. this.setFocusable(true);
  199. background = BitmapFactory.decodeResource(getResources(), R.drawable.staff_bg);
  200. staff = BitmapFactory.decodeResource(getResources(), R.drawable.staff0);
  201. pointer = BitmapFactory.decodeResource(getResources(), R.drawable.kedu_pointer);
  202. this.initValue = initValue;
  203. this.interval = interval;
  204. this.unit = unit;
  205. }
  206. @Override
  207. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  208. }
  209. @Override
  210. public void surfaceCreated(SurfaceHolder holder) {
  211. new Thread(this).start();
  212. }
  213. @Override
  214. public void surfaceDestroyed(SurfaceHolder holder) {
  215. }
  216. @Override
  217. public void run() {
  218. draw(0);
  219. }
  220. private int move = 10; //每次移動的距離
  221. private int initBx = 77; //圖片上X坐標
  222. private int by = 0; //圖片上Y坐標
  223. private int bw = 258; //圖片寬度
  224. private int bh = 31; //圖片高度
  225. private int sx = 18; //畫布X坐標
  226. private int sy = 36; //畫布Y坐標
  227. private int jiange = 51; //大刻度之間距離
  228. private int num_left = 33; //最左邊數字到左邊的距離
  229. private int RESULT_X = 36; //結果的X軸位置
  230. private int RESULT_Y = 25; //結果的Y軸位置
  231. private int RESULT_SIZE = 24; //結果的字體大小
  232. private float result = 0;
  233. /**
  234. * @param direction 方向,-1向左,1向右,0不動
  235. */
  236. public void draw(int direction){
  237. //獲取畫布
  238. canvas = mSurfaceHolder.lockCanvas();
  239. if (mSurfaceHolder == null || canvas == null) {
  240. return;
  241. }
  242. canvas.drawColor(Color.WHITE);
  243. paint.setAntiAlias(true);
  244. paint.setColor(Color.GRAY);
  245. canvas.drawBitmap(background, new Matrix(), paint);
  246. if(isInit){
  247. result = initValue;
  248. }else{
  249. switch(direction){
  250. case 1:
  251. result = Arithmetic.add(result, interval);
  252. break;
  253. case -1:
  254. result = Arithmetic.sub(result, interval);
  255. if(result < 0){
  256. result = 0;
  257. }
  258. break;
  259. }
  260. }
  261. initStaff();
  262. canvas.drawBitmap(pointer, 143, 36, paint);
  263. Paint reslutPaint = new Paint();
  264. reslutPaint.setColor(Color.BLACK);
  265. reslutPaint.setTextSize(RESULT_SIZE);
  266. canvas.drawText(Float.toString(result) + " " + unit, RESULT_X, RESULT_Y, reslutPaint);
  267. //解鎖畫布,提交畫好的圖像
  268. mSurfaceHolder.unlockCanvasAndPost(canvas);
  269. }
  270. private void initStaff(){
  271. int bx = initBx;
  272. int num_x = num_left;
  273. int mod = 0;
  274. int midd = 2;
  275. if(result != 0){
  276. mod = (int)(Arithmetic.div(result, interval, 1) % 5);
  277. bx += mod * move;
  278. }
  279. if(mod >= 3){
  280. midd = 1;
  281. num_x += (5 - mod) * move;
  282. }else{
  283. num_x -= mod * move;
  284. }
  285. float text = 0;
  286. for(int i=0; i<5; i++){
  287. if(i < midd){
  288. text = result - mod * interval - (midd - i) * 5 * interval;
  289. }else if(i == midd){
  290. text = result - mod * interval;
  291. }else{
  292. text += 5 * interval;
  293. }
  294. text = Arithmetic.round(text, 1);
  295. if(text >= 0){
  296. canvas.drawText(Float.toString(text), num_x, 85, paint);
  297. }
  298. num_x += jiange;
  299. }
  300. //要繪制的圖片矩形區域設置
  301. Rect src = new Rect();
  302. src.left = bx;
  303. src.top = by;
  304. src.right = bx + bw;
  305. src.bottom = bh;
  306. //要繪制的畫布矩形區域設置
  307. Rect dst = new Rect();
  308. dst.left = sx;
  309. dst.top = sy;
  310. dst.right = sx + bw;
  311. dst.bottom = sy + bh;
  312. canvas.drawBitmap(staff, src, dst, paint);
  313. }
  314. private float initx = 0;
  315. @Override
  316. public boolean onTouchEvent(MotionEvent event) {
  317. switch(event.getAction()){
  318. case MotionEvent.ACTION_DOWN:
  319. initx = event.getX();
  320. break;
  321. case MotionEvent.ACTION_MOVE:
  322. float lastx = event.getX();
  323. if(lastx > initx + 5){
  324. isInit = false;
  325. draw(-1);
  326. initx = lastx;
  327. }else if(lastx < initx -5){
  328. isInit = false;
  329. draw(1);
  330. initx = lastx;
  331. }
  332. break;
  333. }
  334. return true;
  335. }
  336. public float getResult(){
  337. return result;
  338. }
  339. }
  340. @Override
  341. public boolean onKeyDown(int keyCode, KeyEvent event) {
  342. if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
  343. staff.isInit = false;
  344. staff.draw(-1);
  345. return true;
  346. }if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
  347. staff.isInit = false;
  348. staff.draw(1);
  349. return true;
  350. }
  351. return super.onKeyDown(keyCode, event);
  352. }
  353. }

布局文件:

Xml代碼

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent"
  7. android:gravity="center"
  8. android:background="#fff">
  9. <LinearLayout
  10. android:id="@+id/kedu_linear"
  11. android:layout_width="294dp"
  12. android:layout_height="101dp"/>
  13. <ImageView
  14. android:layout_height="wrap_content"
  15. android:layout_width="wrap_content"
  16. android:id="@+id/kedu_tiao"
  17. android:src="@drawable/kedu_wheel_01"
  18. android:layout_margin="20dp"/>
  19. <LinearLayout
  20. android:id="@+id/staff_linear"
  21. android:layout_width="294dp"
  22. android:layout_height="101dp"/>
  23. </LinearLayout>

運行效果截圖。

Copyright © Linux教程網 All Rights Reserved