使用app:autoSizeTextType="uniform"时TextView描边被裁剪的问题
Hey there! Let's work through that annoying stroke clipping issue you're hitting with your custom TextView. The problem makes total sense—when you use app:autoSizeTextType="uniform", the text expands to fill the TextView's bounds, but your dual strokes (fill + main outline) are drawn outside those bounds and get cut off. Here are three solid solutions to fix this:
1. Add Padding to Make Room for Strokes
The simplest fix is to add padding equal to the total width of your two strokes. This pushes the text inward, leaving space around it for the strokes to render without being clipped.
- Calculate the total stroke width: sum your fill stroke width and main outline width.
- Apply this padding to all four sides of the TextView. You can do this in code (to dynamically adjust if stroke sizes change) or in XML, but code is more flexible for custom views.
Example code snippet for your custom TextView:
private int fillStrokeWidth = 4; // Your fill stroke size private int mainStrokeWidth = 2; // Your main outline size public CustomAutoSizeTextView(Context context, AttributeSet attrs) { super(context, attrs); // Calculate total stroke width int totalStroke = fillStrokeWidth + mainStrokeWidth; // Add padding (keep any existing XML padding by using getPadding*() ) setPadding( getPaddingLeft() + totalStroke, getPaddingTop() + totalStroke, getPaddingRight() + totalStroke, getPaddingBottom() + totalStroke ); }
2. Override onMeasure to Include Stroke Width in Layout
If padding alone isn't enough (especially if your TextView uses fixed dimensions), override onMeasure to ensure the view's measured size accounts for the stroke width. This tells the layout system to reserve extra space for your strokes, so the auto-sizing text doesn't expand into that area.
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int totalStroke = fillStrokeWidth + mainStrokeWidth; // Add twice the stroke width (left/right and top/bottom) int newMeasuredWidth = getMeasuredWidth() + totalStroke * 2; int newMeasuredHeight = getMeasuredHeight() + totalStroke * 2; // Update the measured dimensions setMeasuredDimension(newMeasuredWidth, newMeasuredHeight); }
Pro tip: If your TextView uses wrap_content, this will automatically expand the view to fit the text plus strokes. For fixed dimensions, make sure the parent container has enough space to accommodate the expanded size.
3. Translate the Canvas in onDraw
Another approach is to shift the canvas before drawing the text and strokes, so everything is rendered inside the view's bounds with room to spare. This works well if you don't want to adjust the view's padding or measured size.
@Override protected void onDraw(Canvas canvas) { int totalStroke = fillStrokeWidth + mainStrokeWidth; // Save the canvas state before translating canvas.save(); // Shift the canvas right and down by the total stroke width canvas.translate(totalStroke, totalStroke); // Draw your fill stroke first setPaintStyle(Paint.Style.STROKE); setStrokeWidth(fillStrokeWidth); setTextColor(Color.GRAY); // Your fill stroke color super.onDraw(canvas); // Draw the main outline stroke setStrokeWidth(mainStrokeWidth); setTextColor(Color.BLACK); // Your main outline color super.onDraw(canvas); // Draw the actual text setPaintStyle(Paint.Style.FILL); setTextColor(Color.WHITE); // Your text color super.onDraw(canvas); // Restore the canvas to its original state canvas.restore(); }
Don't forget to pair this with matching padding, otherwise the translated content might get cut off at the edges of the view.
Quick Notes to Avoid Headaches
- Double-check your
autoSizeMinTextSizeandautoSizeMaxTextSizevalues—they should still work correctly once you've added space for strokes. - Test with long text strings and different screen sizes to make sure strokes never get clipped in edge cases.
内容的提问来源于stack exchange,提问作者Ritesh Shakya

