安卓開發自己寫的刻度尺測量,精確到mm.
阿新 • • 發佈:2019-01-06
我也是剛學安卓不久,只不過去實習有個專案需要這樣的功能就寫了,有些也是參考前人的。今天發出來希望對各位朋友有所啟發。原始碼已經註釋很清楚。
效果如下圖:顯示
下面是原始碼.
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