2011-08-29 12 views
26

Sto lavorando all'applicazione Android. Nel mio progetto ho un compito per quanto riguarda firma cattura cioè l'utente deve mantenere il suo/la sua firma sullo schermo del cellulare e una voltaSalva pulsante viene premuto la firma deve memorizzata nel database di . Ho cercato e trovato alcuni collegamenti ma ancora non ho trovato la soluzione esatta. Ho anche provato TouchPaint.java ma non ho trovato il file xml per il layout. Potresti suggerirci qualche codice di esempio? Ti ringrazierò ...Android Signature Capture

+1

Forse questa [domanda correlata] [1] ti fornisce alcuni suggerimenti. [1]: http://stackoverflow.com/questions/4658703/signature-capture-in-phonegap-android-application – Ber

+0

Eventuali duplicati: [necessità di attuare la cattura della firma] (http: // StackOverflow .com/q/3752003/145173) –

risposta

4

probabilmente hai bisogno di generatore di gesti.

penso questo collegamento.

http://android-developers.blogspot.com/2009/10/gestures-on-android-16.html

sarà utile per voi. se è necessario ricontrollare la firma.

UPDATE

stai parlando questo

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html

allora questo esempio non fa uso di XML. esso ha la vista come un classe interna (MyView)

+0

Ciao grazie per la risposta. Ho bisogno solo dell'applicazione TouchPaint. Ma non riesco a visualizzare l'output quando eseguo l'applicazione. Ho bisogno di altri nuovi file da aggiungere per eseguire l'applicazione? Ho già aggiunto due altre classi GraphicsActivity e PictureLayout ... –

+2

puoi trovare l'esempio operativo completo di TouchPaing/FingerPaint in ** com.example.android.apis.graphics ** nelle demo dell'ADD ** di Android sdk ** – Samuel

4

So che questa è una vecchia domanda, ma avevo bisogno di implementare la mia vista per acquisire la firma perché sto usando MonoForAndroid (C# non Java). Quindi sto aggiungendo il mio codice View qui nel caso qualcuno ne abbia bisogno.

using System; 
using Android.Content; 
using Android.Graphics; 
using Android.Views; 

namespace MyApp.Views 
{ 
    public class CaptureSignatureView : View 
    { 
     public CaptureSignatureView(Context c, SignatureData signatureData) : base(c) 
     { 
      SignatureData = signatureData; 
      _Path = new Path(); 
      _BitmapPaint = new Paint(PaintFlags.Dither); 
      _paint = new Paint 
      { 
       AntiAlias = true, 
       Dither = true, 
       Color = Color.Argb(255, 0, 0, 0) 
      }; 
      _paint.SetStyle(Paint.Style.Stroke); 
      _paint.StrokeJoin = Paint.Join.Round; 
      _paint.StrokeCap = Paint.Cap.Round; 
      _paint.StrokeWidth = 8; 
     } 

     protected override void OnSizeChanged(int w, int h, int oldw, int oldh) 
     { 
      base.OnSizeChanged(w, h, oldw, oldh); 
      _Bitmap = Bitmap.CreateBitmap(w, (h > 0 ? h : ((View)this.Parent).Height), Bitmap.Config.Argb8888); 
      _Canvas = new Canvas(_Bitmap); 
     } 

     protected override void OnDraw(Canvas canvas) 
     { 
      canvas.DrawColor(Color.White); 
      canvas.DrawBitmap(_Bitmap, 0, 0, _BitmapPaint); 
      canvas.DrawPath(_Path, _paint); 
     } 

     private float _mX, _mY; 
     private const float TouchTolerance = 4; 

     private void TouchStart(float x, float y) 
     { 
      _Path.Reset(); 
      _Path.MoveTo(x, y); 
      _mX = x; 
      _mY = y; 
      SignatureData.AddPoint(SignatureState.Start, (int)x, (int)y); 
     } 

     private void TouchMove(float x, float y) 
     { 
      float dx = Math.Abs(x - _mX); 
      float dy = Math.Abs(y - _mY); 

      if (dx >= TouchTolerance || dy >= TouchTolerance) 
      { 
       _Path.QuadTo(_mX, _mY, (x + _mX)/2, (y + _mY)/2); 
       SignatureData.AddPoint(SignatureState.Move, (int)x, (int)y); 
       _mX = x; 
       _mY = y; 
      } 
     } 

     private void TouchUp() 
     { 
      if (!_Path.IsEmpty) 
      { 
       _Path.LineTo(_mX, _mY); 
       _Canvas.DrawPath(_Path, _paint); 
      } 
      else 
      { 
       _Canvas.DrawPoint(_mX, _mY, _paint); 
      } 
      SignatureData.AddPoint(SignatureState.End, (int)_mX, (int)_mY); 

      _Path.Reset(); 
     } 

     public override bool OnTouchEvent(MotionEvent e) 
     { 
      var x = e.GetX(); 
      var y = e.GetY(); 

      switch (e.Action) 
      { 
       case MotionEventActions.Down: 
        TouchStart(x, y); 
        Invalidate(); 
        break; 
       case MotionEventActions.Move: 
        TouchMove(x, y); 
        Invalidate(); 
        break; 
       case MotionEventActions.Up: 
        TouchUp(); 
        Invalidate(); 
        break; 
      } 
      return true; 
     } 

     public void ClearCanvas() 
     { 
      _Canvas.DrawColor(Color.White); 
      Invalidate(); 
     } 

     public Bitmap CanvasBitmap() 
     { 
      return _Bitmap; 
     } 

     public void Clear() 
     { 
      ClearCanvas(); 
      SignatureData = new SignatureData(); 
     } 

     #region Implementation 

     private Bitmap _Bitmap; 
     private Canvas _Canvas; 
     private readonly Path _Path; 
     private readonly Paint _BitmapPaint; 
     private readonly Paint _paint; 
     public SignatureData SignatureData; 

     #endregion 
    } 

} 

Inoltre, ho un blog post here che passa attraverso i dettagli di come catturare la firma. Fondamentalmente puoi farlo in due modi diversi. O acquisite la vista con la firma come immagine e salvate quella bitmap (e inviatela magari al server). Oppure puoi semplicemente catturare una serie bidimensionale di punti e ricostruire la firma nel modo che preferisci.

+1

Il tuo "post del blog qui" non esiste. – Pierre

+0

Come si recupera la bitmap dopo il disegno? Sto ottenendo un foglio bianco ogni volta, quando disegno, si attacca. Ma al salvataggio, non è possibile ottenere la bitmap con il disegno? – Pierre

+0

+1 Grazie per il codice, vedere il mio post è la versione java del codice C# – Pierre

29

Ecco la versione Java di lavoro del Has di AlTaiar C# Firma View, ho messo un po 'per farlo funzionare al 100% correttamente

public class CaptureSignatureView extends View { 

    private Bitmap _Bitmap; 
    private Canvas _Canvas; 
    private Path _Path; 
    private Paint _BitmapPaint; 
    private Paint _paint; 
    private float _mX; 
    private float _mY; 
    private float TouchTolerance = 4; 
    private float LineThickness = 4; 

    public CaptureSignatureView(Context context, AttributeSet attr) { 
     super(context, attr); 
     _Path = new Path(); 
     _BitmapPaint = new Paint(Paint.DITHER_FLAG); 
     _paint = new Paint(); 
     _paint.setAntiAlias(true); 
     _paint.setDither(true); 
     _paint.setColor(Color.argb(255, 0, 0, 0)); 
     _paint.setStyle(Paint.Style.STROKE); 
     _paint.setStrokeJoin(Paint.Join.ROUND); 
     _paint.setStrokeCap(Paint.Cap.ROUND); 
     _paint.setStrokeWidth(LineThickness); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     _Bitmap = Bitmap.createBitmap(w, (h > 0 ? h : ((View) this.getParent()).getHeight()), Bitmap.Config.ARGB_8888); 
     _Canvas = new Canvas(_Bitmap); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawColor(Color.WHITE); 
     canvas.drawBitmap(_Bitmap, 0, 0, _BitmapPaint); 
     canvas.drawPath(_Path, _paint); 
    } 

    private void TouchStart(float x, float y) { 
     _Path.reset(); 
     _Path.moveTo(x, y); 
     _mX = x; 
     _mY = y; 
    } 

    private void TouchMove(float x, float y) { 
     float dx = Math.abs(x - _mX); 
     float dy = Math.abs(y - _mY); 

     if (dx >= TouchTolerance || dy >= TouchTolerance) { 
      _Path.quadTo(_mX, _mY, (x + _mX)/2, (y + _mY)/2); 
      _mX = x; 
      _mY = y; 
     } 
    } 

    private void TouchUp() { 
     if (!_Path.isEmpty()) { 
      _Path.lineTo(_mX, _mY); 
      _Canvas.drawPath(_Path, _paint); 
     } else { 
      _Canvas.drawPoint(_mX, _mY, _paint); 
     } 

     _Path.reset(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent e) { 
     super.onTouchEvent(e); 
     float x = e.getX(); 
     float y = e.getY(); 

     switch (e.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       TouchStart(x, y); 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       TouchMove(x, y); 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_UP: 
       TouchUp(); 
       invalidate(); 
       break; 
     } 

     return true; 
    } 

    public void ClearCanvas() { 
     _Canvas.drawColor(Color.WHITE); 
     invalidate(); 
    } 

    public byte[] getBytes() { 
     Bitmap b = getBitmap(); 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     b.compress(Bitmap.CompressFormat.PNG, 100, baos); 
     return baos.toByteArray(); 
    } 

    public Bitmap getBitmap() { 
     View v = (View) this.getParent(); 
     Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888); 
     Canvas c = new Canvas(b); 
     v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); 
     v.draw(c); 

     return b; 
    } 
} 

Ho provato il suggerimento di Rob Croll, che ha funzionato bene, ma è linea retta, rendendo la firma non dall'aspetto umano.Se sai quello che voglio dire: P

Ecco come si aggiunge la vista su un layout lineare vuoto

LinearLayout mContent = (LinearLayout) findViewById(R.id.linearLayout); 
CaptureSignatureView mSig = new CaptureSignatureView(this, null); 
mContent.addView(mSig, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 

Ecco come ottenere i byte o bitmap del Signature

byte[] signature = mSig.getBytes(); 
Bitmap signature = mSig.getBitmap(); 
+0

È possibile verificare se l'utente ha firmato o no? –

+0

@ItuokeAjanlekoko Puoi aggiungere un evento che controlla la lunghezza della linea, se è più di un punto, imposta il flag di bool su true – Pierre

+1

Sì. Ha fatto qualcosa del genere, ma non stavo controllando la lunghezza della linea. L'ho aggiunto in motion event up e motion event down. E se l'utente cancella, diventa falso. Grazie. –