Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strike through substring of text in Android widget

I have a text view in my android widget and I need to strike through only certain lines of text. I found this in another SO question to strike through text in a widget:

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);

// strike through text, this strikes through all text
views.setInt(R.id.appwidget_text, "setPaintFlags", Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);

The problem is this strikes through all text in the text view. How can I strike through only part of the text view's text?

like image 763
Mikkel Bang Avatar asked Dec 17 '25 14:12

Mikkel Bang


2 Answers

Use the SpannableStringBuilder and StrikethroughSpan

For example to get the following effect see the snippet below: enter image description here


String firstWord = "Hello";
String secondWord = "World!";

TextView tvHelloWorld = (TextView)findViewById(R.id.tvHelloWorld);

// Create a span that will make the text red
ForegroundColorSpan redForegroundColorSpan = new ForegroundColorSpan(
    getResources().getColor(android.R.color.holo_red_dark));

// Use a SpannableStringBuilder so that both the text and the spans are mutable
SpannableStringBuilder ssb = new SpannableStringBuilder(firstWord);

// Apply the color span
ssb.setSpan(
    redForegroundColorSpan,            // the span to add
    0,                                 // the start of the span (inclusive)
    ssb.length(),                      // the end of the span (exclusive)
    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // behavior when text is later inserted into the SpannableStringBuilder
                                       // SPAN_EXCLUSIVE_EXCLUSIVE means to not extend the span when additional
                                       // text is added in later

// Add a blank space
ssb.append(" ");

// Create a span that will strikethrough the text
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();

// Add the secondWord and apply the strikethrough span to only the second word
ssb.append(secondWord);
ssb.setSpan(
    strikethroughSpan,
    ssb.length() - secondWord.length(),
    ssb.length(),
    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Set the TextView text and denote that it is Editable
// since it's a SpannableStringBuilder
tvHelloWorld.setText(ssb, TextView.BufferType.EDITABLE);

more cool effects here

like image 130
ΦXocę 웃 Пepeúpa ツ Avatar answered Dec 19 '25 05:12

ΦXocę 웃 Пepeúpa ツ


Xoce's answer is pretty much right but it was more of a general answer for in app textviews, but with some tweaking I have the way to do it for widgets. (Also thanks to CommonsWare for pushing me in the right direction.

In the updateAppWidget method, you can add text to the textview using remote views. To customize substrings of the textview's text with a strike through, use a spannable string builder (you can also use differnt spans to achieve bold, underline, italic, etc.)

Here's what I did:

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                            int appWidgetId) {
    CharSequence widgetText = NewAppWidgetConfigureActivity.loadTitlePref(context, appWidgetId, NewAppWidgetConfigureActivity.TEXT_KEY);
    // Construct the RemoteViews object
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);

    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(widgetText);
    StrikethroughSpan strikethroughSpan = new StrikethroughSpan();

    spannableStringBuilder.setSpan(strikethroughSpan, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    views.setTextViewText(R.id.appwidget_text, spannableStringBuilder);

    ...

}
like image 34
Mikkel Bang Avatar answered Dec 19 '25 07:12

Mikkel Bang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!