I'm creating an app where the user draws a letter on canvas and it gets validated if the draw is an actual letter. I'm using a GestureOverlayView with a canvas inside to capture both the gesture and the path, the problem is that the canvas is not drawing the whole path/gesture i do with my hands. I need help to find the solution. I need the path/gesture to be fully drawn.
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.gesture.GestureOverlayView
android:id="@+id/gestures"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:eventsInterceptionEnabled="true"
android:gestureStrokeType="multiple"
android:layout_alignParentRight="true"
android:fadeOffset="500"
android:background="#000000">
<cohen.projetoTEA.com.DrawLetter
android:id="@+id/drawing"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:background="#FFFFFF"
/>
</android.gesture.GestureOverlayView>
</RelativeLayout>
Activity
public class Reconhecimento extends Activity implements OnGesturePerformedListener {
GestureLibrary mLibrary;
private final File mStoreFile = new File(Environment.getExternalStorageDirectory(), "gestures");
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reconhecimento);
//mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
mLibrary = GestureLibraries.fromFile(mStoreFile);
if (!mLibrary.load()) {
finish();
}
GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(this);
gestures.setGestureVisible(false);
}
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
if (predictions.size() > 0 && predictions.get(0).score > 1.0) {
String result = predictions.get(0).name;
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
if ("open".equalsIgnoreCase(result)) {
Toast.makeText(this, "Opening the document", Toast.LENGTH_LONG).show();
} else if ("save".equalsIgnoreCase(result)) {
Toast.makeText(this, "Saving the document", Toast.LENGTH_LONG).show();
}
}
}
}
DrawLetter app
public class DrawLetter extends View {
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private boolean erase=false;
public DrawLetter(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
private void setupDrawing(){
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(5);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void setErase(boolean isErase){
erase=isErase;
if(erase){
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
drawPaint.setStrokeWidth(10);
}
else{
drawPaint.setXfermode(null);
drawPaint.setStrokeWidth(5);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//view given size
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
//draw view
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//detect user touch
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
invalidate();
return true;
}
public boolean getErase(){ return erase; }
}
You can do it in another way. Like this
Here GestureOverlayView g2 is within g1.
g2 is used to recognize letters and it fades once the letter is written.
But g1 does not fades.
If you don't want the letter you can clear the GestureOverlayView.