Android textview outline text
Is there a simple way to have text be able to have a black outline? I have textviews that will be different colors, but some of the colors don't show up on my background so well, so I was wondering if there's an easy way to get a black outline or something else that will do the job? I'd prefer not to have to create a custom view and make a canvas and such.
outline effect can be achieved using shadow in TextView:
android:shadowColor="#000000"
android:shadowDx="1.5"
android:shadowDy="1.3"
android:shadowRadius="1.6"
android:text="CCC"
android:textAllCaps="true"
android:textColor="@android:color/white"
So, little late, but MagicTextView will do text outlines, amongst other things.
<com.qwerjk.better_text.MagicTextView
xmlns:qwerjk="http://schemas.android.com/apk/res/com.qwerjk.better_text"
android:textSize="78dp"
android:textColor="#ff333333"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
qwerjk:strokeColor="#FFff0000"
qwerjk:strokeJoinStyle="miter"
qwerjk:strokeWidth="5"
android:text="Magic" />
Note: I made this, and am posting more for the sake of future travelers than the OP. It's borderline spam, but being on-topic, perhaps acceptable?
You can put a shadow behind the text, which can often help readability. Try experimenting with 50% translucent black shadows on your green text. Details on how to do this are over here: Android - shadow on text?
To really add a stroke around the text, you need to do something a bit more involved, like this: How do you draw text with a border on a MapView in Android?
It is quite an old question but still I don't see any complete answers. So I am posting this solution, hoping that someone struggling with this problem might find it useful. The simplest and most effective solution is to override TextView class' onDraw method. Most implementations I have seen use drawText method to draw the stroke but that approach doesn't account for all the formatting alignment and text wrapping that goes in. And as a result often the stroke and text end up at different places. Following approach uses super.onDraw to draw both the stroke and fill parts of the text so you don't have to bother about rest of the stuff. Here are the steps
- Extend TextView class
- Override onDraw method
- Set paint style to FILL
- call parent class on Draw to render text in fill mode.
- save current text color.
- Set current text color to your stroke color
- Set paint style to Stroke
- Set stroke width
-
And call parent class onDraw again to draw the stroke over the previously rendered text.
package com.example.widgets; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.Button; public class StrokedTextView extends Button { private static final int DEFAULT_STROKE_WIDTH = 0; // fields private int _strokeColor; private float _strokeWidth; // constructors public StrokedTextView(Context context) { this(context, null, 0); } public StrokedTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public StrokedTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if(attrs != null) { TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.StrokedTextAttrs); _strokeColor = a.getColor(R.styleable.StrokedTextAttrs_textStrokeColor, getCurrentTextColor()); _strokeWidth = a.getFloat(R.styleable.StrokedTextAttrs_textStrokeWidth, DEFAULT_STROKE_WIDTH); a.recycle(); } else { _strokeColor = getCurrentTextColor(); _strokeWidth = DEFAULT_STROKE_WIDTH; } //convert values specified in dp in XML layout to //px, otherwise stroke width would appear different //on different screens _strokeWidth = dpToPx(context, _strokeWidth); } // getters + setters public void setStrokeColor(int color) { _strokeColor = color; } public void setStrokeWidth(int width) { _strokeWidth = width; } // overridden methods @Override protected void onDraw(Canvas canvas) { if(_strokeWidth > 0) { //set paint to fill mode Paint p = getPaint(); p.setStyle(Paint.Style.FILL); //draw the fill part of text super.onDraw(canvas); //save the text color int currentTextColor = getCurrentTextColor(); //set paint to stroke mode and specify //stroke color and width p.setStyle(Paint.Style.STROKE); p.setStrokeWidth(_strokeWidth); setTextColor(_strokeColor); //draw text stroke super.onDraw(canvas); //revert the color back to the one //initially specified setTextColor(currentTextColor); } else { super.onDraw(canvas); } } /** * Convenience method to convert density independent pixel(dp) value * into device display specific pixel value. * @param context Context to access device specific display metrics * @param dp density independent pixel value * @return device specific pixel value. */ public static int dpToPx(Context context, float dp) { final float scale= context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); } }
That is all. This class uses custom XML attributes to enable specifying stroke color and width from the XML layout files. Therefore, you need to add these attributes in your attr.xml file in subfolder 'values' under folder 'res'. Copy and paste the following in your attr.xml file.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="StrokedTextAttrs">
<attr name="textStrokeColor" format="color"/>
<attr name="textStrokeWidth" format="float"/>
</declare-styleable>
</resources>
Once you are done with that, you can use the custom StrokedTextView class in your XML layout files and specify stroke color and width as well. Here is an example
<com.example.widgets.StrokedTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stroked text sample"
android:textColor="@android:color/white"
android:textSize="25sp"
strokeAttrs:textStrokeColor="@android:color/black"
strokeAttrs:textStrokeWidth="1.7" />
Remember to replace package name with your project's package name. Also add the xmlns namespace in the layout file in order to use custom XML attributes. You can add the following line in your layout file's root node.
xmlns:strokeAttrs="http://schemas.android.com/apk/res-auto"