What would be the best way to determine screen size in an external class and then adjust the stroke width of a handwriting capture view, so that it scales nicely?
I've got this SignatureCanvas.java class, in an external library. As you can see I've set the stroke width to a constant, which works (nothing strange there!). However, as I've been testing on various devices and emaulators (of differing screen size), the stroke width isn't translated to any kind of under-the-hood pixel->dip (which is understandable!). So, on older/smaller screen sizes, this stroke width of 8, actually looks like it's 14, and the signature becomes unreadable.
I've brainstormed a bit and have come up with the idea of generalising screen resolutions and having a default stroke width for each 'bracket' (so to speak), and applying it as and when I need to. However, that seems a bit rubbish and I was wondering if anyone has had this dilemma previously and how you solved it?
The class is here purely for demonstration purposes, there is nothing wrong with the code per-se.
package com.goosesys.gooselib.Views; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class SignatureCanvas extends View { private final float STROKE_WIDTH = 8f; private final boolean ANTI_ALIAS = true; private final int DEFAULT_PEN_COLOUR = 0xFF000000; private Path drawPath; private Paint drawPaint; private Paint canvasPaint; private int paintColour = DEFAULT_PEN_COLOUR; private Canvas drawCanvas; private Bitmap canvasBitmap; /* * Constructors */ // Main in-code constructor // public SignatureCanvas(Context context) { super(context); setupDrawing(); } // Constructor for use in UI layout tool - Custom Views public SignatureCanvas(Context context, AttributeSet attributeSet){ super(context, attributeSet); setupDrawing(); } /* * Methods */ private void setupDrawing(){ drawPath = new Path(); drawPaint = new Paint(); // set initial colour for drawing drawPaint.setColor(paintColour); // setup paths drawPaint.setAntiAlias(ANTI_ALIAS); drawPaint.setStrokeWidth(STROKE_WIDTH); drawPaint.setStyle(Paint.Style.STROKE); drawPaint.setStrokeJoin(Paint.Join.ROUND); drawPaint.setStrokeCap(Paint.Cap.ROUND); // finally create a new canvas paint object canvasPaint = new Paint(Paint.DITHER_FLAG); } public void clearCanvas(){ drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR); invalidate(); } public Bitmap saveSignature(){ return Bitmap.createBitmap(canvasBitmap); } /* * (non-Javadoc) * @see android.view.View#onSizeChanged(int, int, int, int) */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh){ super.onSizeChanged(w, h, oldw, oldh); // view given size 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; } }