安卓开发自己写的刻度尺测量,精确到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>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值