2012-04-09 29 views
1

我正在開發一個Android數字簽名應用程序,用戶可以在其中籤名,並且我必須將該文件保存爲image.i使用SurfaceView進行繪製。 DigitalSignatureActivity有兩個按鈕保存,清除。 1.保存按鈕將文件保存爲圖像 2.清除按鈕以清除表面。 但我無法清除surface.i嘗試drawingSurface.setBackgroundColor(Color.BLACK);仍然以前的標誌被保留並且canvas.drawColor(Color.BLACK);沒有效果和 我能夠保存文件,但它沒有完美地存儲簽名(有些內容丟失)請幫助。 我的代碼是: DigitalSignatureActivity.java如何清除表面視圖中的畫布?

package com.pop.digitalsign; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.os.Bundle; 
import android.os.Environment; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Toast; 

public class DigitalSignatureActivity extends Activity implements 
     View.OnTouchListener { 

    private DrawingSurface drawingSurface; 
    private DrawingPath currentDrawingPath; 
    private Paint currentPaint; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     setCurrentPaint(); 
     drawingSurface = (DrawingSurface) findViewById(R.id.drawingSurface); 
     drawingSurface.setOnTouchListener(this); 

    } 

    private void setCurrentPaint() { 
     currentPaint = new Paint(); 
     currentPaint.setDither(true); 
     currentPaint.setColor(Color.WHITE); 
     currentPaint.setStyle(Paint.Style.STROKE); 
     currentPaint.setStrokeJoin(Paint.Join.ROUND); 
     currentPaint.setStrokeCap(Paint.Cap.ROUND); 
     currentPaint.setStrokeWidth(2); 

    } 

    public boolean onTouch(View view, MotionEvent motionEvent) { 
     if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 

      drawingSurface.setBackgroundColor(0); 
      currentDrawingPath = new DrawingPath(); 
      currentDrawingPath.paint = currentPaint; 
      currentDrawingPath.path = new Path(); 
      currentDrawingPath.path.moveTo(motionEvent.getX(), 
        motionEvent.getY()); 
      currentDrawingPath.path.lineTo(motionEvent.getX(), 
        motionEvent.getY()); 

     } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) { 
      currentDrawingPath.path.lineTo(motionEvent.getX(),motionEvent.getY()); 
      drawingSurface.addDrawingPath(currentDrawingPath); 

     } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) { 
      currentDrawingPath.path.lineTo(motionEvent.getX(),motionEvent.getY()); 
     } 

     return true; 
    } 
    //To save file as Image 
    public void saveDrawing(View v) throws IOException { 

     File mediaStorageDir = new File(
       Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), 
       "MySignatures"); 

     Bitmap nBitmap = drawingSurface.getBitmap(); 
     try { 
      if (!mediaStorageDir.exists()) { 
       mediaStorageDir.mkdirs(); 
      } 
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") 
        .format(new Date()); 
      File mediaFile = new File(mediaStorageDir.getPath() 
        + File.separator + "SIGN_" + timeStamp + ".png"); 
      FileOutputStream out = new FileOutputStream(mediaFile); 

      nBitmap.compress(Bitmap.CompressFormat.PNG, 90, out); 
      out.flush(); 
      out.close(); 
      Toast.makeText(this, "Signature saved to " + mediaFile, 
        Toast.LENGTH_LONG).show(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      Toast.makeText(getApplicationContext(), "Not saved", 
        Toast.LENGTH_SHORT).show(); 
     } 

    } 

    //To clear Surface 
    public void clearScreen(View v) { 
     //drawingSurface.setBackgroundColor(Color.BLACK); 
     drawingSurface.clear(); 
    } 
} 

DrawingSurface.java

package com.pop.digitalsign; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.PorterDuff; 
import android.util.AttributeSet; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 


public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback { 
    private Boolean _run; 
    protected DrawThread thread; 
    private Bitmap mBitmap; 
    Canvas canvas; 


    private CommandManager commandManager; 

    public DrawingSurface(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     getHolder().addCallback(this); 
     commandManager = new CommandManager(); 
     thread = new DrawThread(getHolder()); 
    } 


    class DrawThread extends Thread{ 

     public SurfaceHolder mSurfaceHolder; 

     public DrawThread(SurfaceHolder surfaceHolder){ 
      mSurfaceHolder = surfaceHolder; 

     } 
     public DrawThread() { 
      // TODO Auto-generated constructor stub 
     } 

     public void setRunning(boolean run) { 
      _run = run; 
     } 


     @Override 
     public void run() { 
      canvas = null; 
      while (_run){ 
       try{ 
        canvas = mSurfaceHolder.lockCanvas(null); 
        //canvas.drawColor(Color.WHITE); 
        if(mBitmap == null){ 
         mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);; 
        } 
        final Canvas c = new Canvas (mBitmap); 
        c.drawColor(0, PorterDuff.Mode.CLEAR); 
        commandManager.executeAll(c); 
        canvas.drawBitmap (mBitmap, 0, 0,null); 
       } finally { 
        if(canvas!=null){ 
         mSurfaceHolder.unlockCanvasAndPost(canvas); 
        } 
       } 
      } 
     } 
    } 


    public void addDrawingPath (DrawingPath drawingPath){ 
     commandManager.addCommand(drawingPath); 
    } 


    public void clear(){ 
     //Here i want to clear surface 
     canvas.drawColor(Color.BLACK);//it has no effect 
    } 

    public boolean hasMoreUndo(){ 
     return commandManager.hasMoreUndo(); 
    } 

    public Bitmap getBitmap(){ 
     return mBitmap; 
    } 


    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     mBitmap = Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888);; 
    } 


    public void surfaceCreated(SurfaceHolder holder) { 
     thread.setRunning(true); 
     thread.start(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     boolean retry = true; 
     thread.setRunning(false); 
     while (retry) { 
      try { 
       thread.join(); 
       retry = false; 
      } catch (InterruptedException e) { 
      } 
     } 
    } 

} 

CommandManager.java

package com.pop.digitalsign; 

import android.graphics.Canvas; 

import java.util.Iterator; 
import java.util.List; 
import java.util.Collections; 
import java.util.ArrayList; 


public class CommandManager { 
    private List<DrawingPath> currentStack; 

    public CommandManager(){ 
     currentStack = Collections.synchronizedList(new ArrayList<DrawingPath>()); 
    } 

    public void addCommand(DrawingPath command){ 
     currentStack.add(command); 
    } 

    public void undo(){ 
     final int length = currentStackLength(); 
     if (length > 0) { 
      final DrawingPath undoCommand = currentStack.get( length - 1 ); 
      currentStack.remove(length - 1); 
      undoCommand.undo(); 
     } 
    } 

    public int currentStackLength(){ 
     final int length = currentStack.toArray().length; 
     return length; 
    } 


    public void executeAll(Canvas canvas){ 
     if(currentStack != null){ 
      synchronized(currentStack) { 
       final Iterator<?> i = currentStack.iterator(); 
       while (i.hasNext()){ 
        final DrawingPath drawingPath = (DrawingPath) i.next(); 
        drawingPath.draw(canvas); 
       } 
      } 
     } 
    } 

    public boolean hasMoreUndo(){ 
     return currentStack.toArray().length > 0; 
    } 
} 

DrawingPath.java

package com.pop.digitalsign; 

import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Path; 

public class DrawingPath { 
    public Path path; 
    public Paint paint; 

    public void draw(Canvas canvas) { 
     canvas.drawPath(path, paint); 
    } 

    public void undo() { 
    } 
} 

main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" 
    android:background="@android:color/white" > 

    <com.pop.digitalsign.DrawingSurface 
     android:id="@+id/drawingSurface" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     /> 

     <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     android:gravity="center" > 

     <Button 
      android:id="@+id/saveBtn" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:onClick="saveDrawing" 
      android:text="@string/save" /> 
     <Button 
      android:id="@+id/clearBtn" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:onClick="clearScreen" 
      android:text="@string/clear" /> 
     </LinearLayout> 

</RelativeLayout> 
+0

這裏沒有任何答案是有價值的。我有同樣的問題,有人可以爲我回答嗎? – 2013-07-19 19:06:44

+0

請在下面的鏈接,它爲我 [鏈接] [1] [1]:http://stackoverflow.com/a/20403404/3009917 – user3009917 2013-12-05 17:14:49

回答

-1

DrawingSurface添加此方法

public void resetCanvas(){ commandManager.clearAllPath(); } 

,當你需要行動明確調用此方法..

objectNameofDrawingSurefaceClass.resetCanvas(); 

CommandManager

添加代碼
public void clearAllPath(){currentStack.clear(); } 

確定..

+0

感謝回覆,但什麼是ClearAllPath(),它在CommandManager類中不存在 – 2012-04-09 11:00:16

+0

我編輯我的答案,檢查它... – 2012-04-09 11:34:39

+0

我添加了但不工作..... – 2012-04-09 11:41:36

1

最好的建議,我已經是使用這個

if (surfaceHolder.getSurface().isValid()) { 
        Canvas c = surfaceHolder.lockCanvas(); 
        if (first >= 0) { 
         c.drawARGB(255, 255, 255, 255); 
         first--; 
        } 

第一的值是2,你可以使用你想要的每一個名字。 原因是畫布是雙重緩衝的,所以你需要通過將它畫成白色來清除兩個畫面。 這會停止閃爍

+0

記得解鎖它後,除非你正在做其他 – 2013-01-06 03:52:55

+0

這樣你可以將其清除爲任何你想要的顏色。白藍色......無論如何 – 2013-01-06 11:01:21

0
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)