Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android UI設計系列之自定義DrawView組件實現數字簽名效果(5)

Android UI設計系列之自定義DrawView組件實現數字簽名效果(5)

編輯:關於Android編程

最近項目中有個新的需求,用戶在完交易需要進行輸入支付密碼付款的時候,要讓用戶簽下自己的簽名,提起到數字簽名這個東西,感覺有點高大上,後來想想數字簽名的原理也不是太復雜,主要實現原理就是利用了View的繪圖原理,把用戶在屏幕上的手指移動軌跡顯示在屏幕上,接著把在屏幕上顯示的軌跡View轉換成一張圖片,最後把圖片保存到本地或者上傳到服務器...
還是老規矩,首先看一下工程目錄吧:

public class DrawView extends View { 
 
 /** 
  * 簽名畫筆 
  */ 
 private Paint paint; 
 /** 
  * 簽名畫布 
  */ 
 private Canvas cacheCanvas; 
 /** 
  * 畫筆路徑 
  */ 
 private Path path; 
 /** 
  * 緩存圖片 
  */ 
 private Bitmap cacheBitmap; 
 /** 
  * 圖片寬度 
  */ 
 private int width; 
 /** 
  * 圖片高度 
  */ 
 private int height; 
 /** 
  * 手指觸摸屏幕時的X,Y坐標 
  */ 
 private float xDown, yDown; 
 /** 
  * 是否正在繪制 
  */ 
 private boolean isDrawing = false; 
 
 /** 
  * 默認畫筆顏色 
  */ 
 private int paintColor = Color.CYAN; 
 
 /** 
  * 默認畫板背景色 
  */ 
 private int canvasColor = Color.parseColor("#bbccaa"); 
 
 public DrawView(Context context, int width, int height) { 
  super(context); 
  this.width = width; 
  this.height = height; 
  initWedgits(); 
 } 
 
 /** 
  * 初始化組件 
  */ 
 private void initWedgits() { 
  try { 
   paint = new Paint(Paint.DITHER_FLAG); 
   // 設置抗鋸齒 
   paint.setAntiAlias(true); 
   // 設置畫筆寬度 
   paint.setStrokeWidth(3); 
   paint.setDither(true); 
   // 設置樣式 
   paint.setStyle(Paint.Style.STROKE); 
   paint.setStrokeJoin(Paint.Join.ROUND); 
   paint.setStrokeCap(Paint.Cap.ROUND); 
   // 畫筆顏色 
   paint.setColor(paintColor); 
   // 繪制路徑 
   path = new Path(); 
   // 創建空緩存圖片 
   cacheBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); 
   // 把畫布內容畫到空緩存圖片上 
   cacheCanvas = new Canvas(cacheBitmap); 
  } catch (Exception e) { 
   e.printStackTrace(); 
  } 
 } 
  
 @Override 
 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
  super.onSizeChanged(w, h, oldw, oldh); 
 } 
 
 @Override 
 protected void onDraw(Canvas canvas) { 
  super.onDraw(canvas); 
 
  canvas.drawColor(canvasColor); 
  canvas.drawBitmap(cacheBitmap, 0, 0, paint); 
  canvas.drawPath(path, paint); 
 } 
 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
  // 記錄手指摁下屏幕時的X坐標 
  final float x = event.getX(); 
  // 記錄手指摁下屏幕時的Y坐標 
  final float y = event.getY(); 
  switch (event.getAction()) { 
  case MotionEvent.ACTION_DOWN: 
   // 手指摁下時清空之前的設置 
   path.reset(); 
   // 設置路徑起始點 
   path.moveTo(x, y); 
   xDown = x; 
   yDown = y; 
   isDrawing = true; 
   break; 
  case MotionEvent.ACTION_MOVE: 
   // 移動下一點 
   path.quadTo(xDown, yDown, x, y); 
   // 重新設置起點 
   xDown = x; 
   yDown = y; 
   isDrawing = true; 
   break; 
  case MotionEvent.ACTION_UP: 
   path.lineTo(xDown, yDown); 
   // 手指抬起時繪制路徑 
   cacheCanvas.drawPath(path, paint); 
   // 路徑重置 
   path.reset(); 
   isDrawing = false; 
   break; 
  default: 
   break; 
  } 
  // 刷新界面 
  invalidate(); 
  return true; 
 } 
 
 /** 
  * 設置畫筆顏色 
  * 
  * @param color 
  *   畫筆顏色 
  */ 
 public void setPaintColor(int color) { 
  paintColor = color; 
 } 
 
 /** 
  * 設置畫板顏色 
  * 
  * @param color 
  *   畫板顏色 
  */ 
 public void setCanvasColor(int color) { 
  canvasColor = color; 
 } 
 
 /** 
  * 返回繪畫狀態 
  * 
  * @return【true:正在繪制】【false:繪制完成】 
  */ 
 public boolean getDrawState() { 
  return isDrawing; 
 } 
 
 /** 
  * 返回Bitmap 
  * 
  * @return 返回繪制的圖片 
  */ 
 public Bitmap getBitmap() { 
  return cacheBitmap; 
 } 
} 

DrawView的代碼注釋都很清晰,我還是大致說下DrawView的執行邏輯吧,DrawView繼承了View也就是說具有了View的所有功能,要實現圖片繪制就要實現onDraw()方法,要實現對手指在屏幕上的軌跡繪制就需要獲取軌跡坐標,所以需要重寫onTouchEvent()放法,重點在onTouchEvent()方法中。當手指摁下時我們繪制起點,但是在繪制起點前需要先調用path.reset()方法,防止path進行二次重繪,path的moveTo方法就是來繪制當前觸摸事件的起點,摁下完成之後調用inValidate()方法進行界面刷新。當手指移動時調用path.quadTo()方法,這個方法就是追加的意思,把新坐標點追加到path中,手指移動之後再調用inValidate()方法進行界面刷新,最後當手指抬起時,把在當前事件周期內的軌跡繪制到畫板cacheCanvas上,最後再調用inValidate()方法進行界面刷新,因此一次的手指移動軌跡就繪制完成,當要進行下一次的繪制,就是重復以上操作了...

接下來我們看看DrawView的使用吧,首先看一下布局文件:

<?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:background="#ffffff"> 
 
 <TextView 
  android:id="@+id/title" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:text="請繪制簽名" 
  android:textSize="18sp" 
  android:layout_margin="5dip" 
  android:gravity="center" 
  android:textColor="#000000" /> 
 
 <FrameLayout 
  android:id="@+id/contents" 
  android:layout_width="fill_parent" 
  android:layout_height="0dip" 
  android:layout_weight="1" 
  android:layout_gravity="center" 
  android:background="#aabbcc"> 
 </FrameLayout> 
 
 <Button 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" 
  android:onClick="save" 
  android:text="保存簽名" /> 
</LinearLayout> 

乍一看布局文件中並沒有使用我們自定義的DrawView,不過不用著急我是使用了通過在FrameLayout中動態添加的方法把DrawView添加進來的,好了,那緊接著看看MainActivity中的代碼實現吧:

public class MainActivity extends Activity { 
 
 private FrameLayout frameLayout; 
 private DrawView drawView; 
 private TextView title; 
 
 /** Called when the activity is first created. */ 
 @Override 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main); 
 
  initWedgits(); 
 } 
 
 /** 
  * 初始化組件 
  */ 
 private void initWedgits() { 
  try { 
   frameLayout = (FrameLayout) findViewById(R.id.contents); 
   title = (TextView) findViewById(R.id.title); 
   title.setText(Html.fromHtml("<b>China中國<tt>中國</tt></b>China真偉大!")); 
 
  } catch (Exception e) { 
   e.printStackTrace(); 
  } 
 } 
 
 @Override 
 public void onWindowFocusChanged(boolean hasFocus) { 
  drawView = new DrawView(MainActivity.this, frameLayout.getWidth(), frameLayout.getHeight()); 
  frameLayout.addView(drawView); 
 } 
 
 /** 
  * 保存圖片 
  * 
  * @param view 
  */ 
 public void save(View view) { 
  try { 
   File file = new File(Environment.getExternalStorageDirectory() 
     .getAbsolutePath() + "/handle.png"); 
   if (file.exists()) { 
    file.delete(); 
   } 
   file.createNewFile(); 
   if (drawView.getBitmap().compress(CompressFormat.PNG, 100, new FileOutputStream(file))) { 
    Toast.makeText(getApplicationContext(), "圖片保存成功", 1000).show(); 
   } 
  } catch (Exception e) { 
   e.printStackTrace(); 
  } 
 } 
} 

在MainActivity中的代碼沒什麼好解釋的,相信你一看就懂,最主要的是在save方法中使用了Bitmap的compress()方法,就是把圖片存儲在文件中,當我們簽名結束之後點擊保存簽名按鈕,簽名圖片就保存在了本地文件中了,當然了如果你想上傳到後台服務器也不難,就是使用個異步操作進行圖片上傳就行了...

說明:當你運行程序的時候,會看見China中國中國真偉大!的字樣,其中China中國是加粗的效果,因為項目中有個需求讓把漢字也加粗,上網上找了些方法,但是都是對英文和數字有效果對中文暫時沒效果,我也是無意看源碼中的注釋,其中注釋裡邊有加粗的文字說明,我就點擊進去了,結果發現注釋裡的標簽是<tt></tt>,當時腦子一轉就想估計<tt>標簽可以實現對漢字的加粗效果,呵呵,功夫不付有心人,把<tt>標簽放到<b>裡邊已測試,果然有效果,呵呵,當時高興壞了,現在再高興一下,(*^__^*) 嘻嘻...

好了,現在我們運行程序來看一下效果圖吧:

繪制簽名:

當點擊了保存按鈕後,進入圖庫看看吧:

好了,數字簽名的講解到這裡了,謝謝大家的閱讀。

源碼下載: Android UI實現數字簽名效果

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved