1. 程式人生 > >安卓開發自己寫的刻度尺測量,精確到mm.

安卓開發自己寫的刻度尺測量,精確到mm.

我也是剛學安卓不久,只不過去實習有個專案需要這樣的功能就寫了,有些也是參考前人的。今天發出來希望對各位朋友有所啟發。原始碼已經註釋很清楚。
效果如下圖:顯示




下面是原始碼.

MainActivity.java

package cizi.com.example.cizi;

import android.annotation.SuppressLint;
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.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity {
	// 自定義佈局
	public RelativeLayout rtLayout;
	// 類物件
	public MyBgrView myBgrView;
	private MyDrawLine myDrawLine;
	public TextView tv_num;
	// 螢幕屬性
	private int scr_w;
	// 結果提示資訊
	public String str = "100";
	// 第一次佈局View.lyout(View.Layout放在Acticity無效)
	private boolean b_ctlView = false;
	// 距離頂部
	final public int top = 50;
	// 背景邊距剪下
	public float ali_cut;
	//螢幕解析度
	public DisplayMetrics dm = new DisplayMetrics();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//這個是動態添加布局
		rtLayout = (RelativeLayout) findViewById(R.id.myRtLayout);
		myBgrView = new MyBgrView(this);
		myDrawLine = new MyDrawLine(this);
		rtLayout.addView(myBgrView);
		rtLayout.addView(myDrawLine);
		
		myBgrView.setOnTouchListener(keduListener);
		// 獲取螢幕高寬
		WindowManager wmManager = this.getWindowManager();
		scr_w = wmManager.getDefaultDisplay().getWidth();
	}

	public int getScr_w() {
		return scr_w;
	}

	public boolean getCtlView() {
		return b_ctlView;
	}

	public void CclNum(View v, MotionEvent event,int lastX, int lastY){
		double f;
		// 移動中動態設定位置
		int dx = (int) event.getRawX() - lastX;
		//int dy = (int) event.getRawY() - lastY;
		int left = v.getLeft() + dx;
		int top = v.getTop();
		int right = v.getRight() + dx;
		int bottom = v.getBottom();
		// 防止超出刻度線
		if (left > scr_w >> 1) {
			left = scr_w >> 1;
			right = left + v.getWidth();
		}
		if (right < (scr_w >> 1) + ali_cut * 2) {
			right = (scr_w >> 1) + (int) ali_cut * 2;
			left = right - v.getWidth();
		}
		//這個是以圖片最左端位置來計算刻度與數字顯示的正確位置
		//(演算法原理大概是以長度計算佔總長度的幾分之幾*乘以劃分的份數此處刻度份數200)
		f = (((scr_w >> 1) - v.getLeft() + ali_cut) * 200.0 / ((v
				.getRight() - ali_cut) - (v.getLeft() + ali_cut)));
		int f1 = (int) f;
		//偏差1,可能演算法問題
		if (f1 < 0)
			f1 = 0;
		else if (f1 > 201)
			f1 = 201;
		f1--;
		//賦值顯示
		str = f1 + "mm";
		//重新移動佈局
		v.layout(left, top, right, bottom);
	}
	
	// 監聽
	@SuppressLint("ClickableViewAccessibility")
	private ImageView.OnTouchListener keduListener = new ImageView.OnTouchListener() {
		int lastX, lastY;
		/**
		 * @param v
		 * @param event
		 * @return
		 */
		public boolean onTouch(View v, MotionEvent event) {
			int action = event.getAction();
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				b_ctlView = true;
				// getRaw相對於手機左上角
				lastX = (int) event.getRawX();
				lastY = (int) event.getRawY();
				break;
			case MotionEvent.ACTION_MOVE:
				CclNum(v, event, lastX, lastY);
				lastX = (int) event.getRawX();
				lastY = (int) event.getRawY();
				break;
			case MotionEvent.ACTION_UP:
				break;
			default:
				break;
			}
			return true;
		}
	};

	//DrawImg
	public void DrawImg(Canvas canvas, Bitmap bmp, int x, int y, int w, int h,int bx, int by) {
		Rect src_rect = new Rect();
		Rect dst_rect = new Rect();
	
		// src_rect表示繪製圖片的部分
		src_rect.left = bx;
		src_rect.top = by;
		src_rect.right = bx + w;
		src_rect.bottom = by + h;
	
		// dst_rect表示繪製的螢幕上的區域
		dst_rect.left = x;
		dst_rect.top = y;
		dst_rect.right = x + w;
		dst_rect.bottom = y + h;
		canvas.drawBitmap(bmp, src_rect, dst_rect, null);
	}

	public void DrawText(Canvas canvas,String strText,String strNum) {
		Paint paint = new Paint();
		paint.setStyle(Paint.Style.FILL);
		paint.setStrokeWidth(4);
		// 字型顯示提示
		// 設定此項之後繪製的x,y表示字型的中心
		paint.setTextAlign(Paint.Align.CENTER);

		// 計算或者試著字型屬性
		paint.setTextSize(35);
		paint.setColor(Color.LTGRAY);
		FontMetrics fontMetrics = paint.getFontMetrics();

		//獲取字型寬高
		float fh = fontMetrics.bottom - fontMetrics.top;
		float fw = paint.measureText(strNum);
		
		//還差半個字
		float fw1 = paint.measureText("壠");
		canvas.drawText(strText, ((int)fw >> 1) + ((int)fw1 >> 1), 60 - ((int) fh >> 1), paint);
		//字型顏色
		paint.setColor(Color.GREEN);
		fh = fontMetrics.bottom - fontMetrics.top;
		canvas.drawText(strNum, (getScr_w() >> 1) + 10 + ((int)fw1 >> 1), 60 - ((int) fh >> 1), paint);
	}
	
	//畫線遊標
	public void DrawLine(Canvas canvas,Paint paint){	
		canvas.drawLine(getScr_w() >> 1, 50, getScr_w() >> 1, 100,paint);
	}
}

//用於繪製背景
class MyBgrView extends View {
	static MainActivity mActivity = null;
	// 繪製屬性
	private int w;
	private int h;
	private Bitmap bmp;
	// 螢幕寬度
	private int scr_w;

	public MyBgrView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		mActivity = (MainActivity) context;
		bmp = BitmapFactory.decodeResource(getResources(), R.drawable.kedu);
		w = bmp.getWidth();
		h = bmp.getHeight();
		//如果有多個可以這樣設定標籤
		//this.setTag("MyBgrView");
	}
	
	//
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		 if (mActivity.getCtlView() == false)
	        {
				scr_w = mActivity.getScr_w();
				// 計算應該剪下空白邊距
				mActivity.ali_cut = w / (float) 203.6 * (float) 1.8;
				// 中間顯示
				int sw = (scr_w >> 1) - (w >> 1) + (int) mActivity.ali_cut;
				this.layout(sw, 0, w + sw, h + mActivity.top);
				this.setTop(mActivity.top);
			}
		mActivity.DrawImg(canvas, bmp, 0, 0, w, h, 0,0);
	}

}

//畫線類
@SuppressLint("DrawAllocation")
class MyDrawLine extends View {
	private MainActivity mActivity = null;

	public MyDrawLine(Context context) {
		super(context);
		mActivity = (MainActivity) context;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Paint paint = new Paint();
		paint.setColor(Color.RED);
		paint.setStyle(Paint.Style.FILL);
		paint.setStrokeWidth(4);
		mActivity.DrawText(canvas, "總量",mActivity.str);
		mActivity.DrawLine(canvas,paint);
		invalidate();
	}
}

佈局檔案:activity_main.xml
<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="${relativePackage}.${activityClass}" >

     <RelativeLayout
        android:id="@+id/myRtLayout"
        android:layout_width="wrap_content"
        android:layout_height="110dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"/>

</LinearLayout>



下面是DEMO連結,是百度雲,為什麼在這找不到上傳檔案的地方驚恐。要是有什麼問題可以發我QQ郵箱:[email protected]

連結:http://pan.baidu.com/s/1sj85soX 密碼:elc0