From cf5df22ccefae252a77b21119d56f86eeac5217c Mon Sep 17 00:00:00 2001 From: conradchen Date: Wed, 17 Nov 2021 15:36:46 +0000 Subject: [PATCH] [TextField] Fix crashes when text field size is too large When we try to draw cutout on text field borders, we draw the stroke on a bitmap first. However if the text field is too large, the bitmap size will be too large and cannot be drawn back to the real canvas, which causes crashes. Adds a workaround/fallback solution to avoid the crash. PiperOrigin-RevId: 410523013 --- .../material/textfield/CutoutDrawable.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/java/com/google/android/material/textfield/CutoutDrawable.java b/lib/java/com/google/android/material/textfield/CutoutDrawable.java index b71dc07560b..8169a3ad092 100644 --- a/lib/java/com/google/android/material/textfield/CutoutDrawable.java +++ b/lib/java/com/google/android/material/textfield/CutoutDrawable.java @@ -96,18 +96,25 @@ protected void drawStrokeShape(@NonNull Canvas canvas) { super.drawStrokeShape(canvas); return; } - Bitmap bitmap = - Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); - Canvas tempCanvas = new Canvas(bitmap); - - // Draw the stroke on the temporary canvas - super.drawStrokeShape(tempCanvas); - - // Draw mask for the cutout. - tempCanvas.drawRect(cutoutBounds, cutoutPaint); - - // Draw the temporary canvas back to the original canvas - canvas.drawBitmap(bitmap, 0, 0, null); + try { + Bitmap bitmap = + Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); + Canvas tempCanvas = new Canvas(bitmap); + + // Draw the stroke on the temporary canvas + super.drawStrokeShape(tempCanvas); + + // Draw mask for the cutout. + tempCanvas.drawRect(cutoutBounds, cutoutPaint); + + // Draw the temporary canvas back to the original canvas + canvas.drawBitmap(bitmap, 0, 0, null); + } catch (RuntimeException e) { + // Bitmap is too big to draw, directly paint cutout on the canvas. + // TODO(b/205774869): find a better way to only draw part of the stroke to avoid the issue. + super.drawStrokeShape(canvas); + canvas.drawRect(cutoutBounds, cutoutPaint); + } } private void preDraw(@NonNull Canvas canvas) {