Is there an easy way to strike through text in an app widget?
Asked Answered
C

22

164

I was wondering if there is an easy way to strike text within an app widget in Android. In a normal activity, it is pretty easy, using textview flags:

textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

But since in an app widget, I can use only remoteviews... I do not know if this is possible

Anyone know something about this?

Thanks!

Cowan answered 7/10, 2010 at 12:21 Comment(1)
If you want xml-only solution like me: https://mcmap.net/q/145988/-can-i-define-middle-lined-text-in-an-android-layout-xml-fileRiddle
R
75

You can use this:

remoteviews.setInt(R.id.YourTextView, "setPaintFlags", Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);

Of course you can also add other flags from the android.graphics.Paint class.

Rufina answered 9/10, 2011 at 11:12 Comment(3)
Don't know how this hasn't get more votes, it perfectly answers the question. Thanks.Mullens
First it is unclear what is remoteviews , plus doesn't work for all android versions.Lexical
This is the answer we are looking for, working with app-widgets on androidTextViews are only accessible through removeViews. Accessing TextView directly is not possible at this point.Chaco
E
216

To do it programatically in a textview, untested in other views >>

TextView tv = (TextView) findViewById(R.id.mytext);
tv.setText("This is strike-thru");
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
Expediency answered 18/7, 2011 at 21:22 Comment(1)
This is not possible for App-Widgets. They only work with RemoteViews and there is no method to read the paint flags.Tenedos
C
88

Another way to do it programmatically which looks a bit less like a hack than the Paint way:

Instead of doing:

tv.setText(s);

do:

private static final StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan();
...
tv.setText(s, TextView.BufferType.SPANNABLE);
Spannable spannable = (Spannable) tv.getText();
spannable.setSpan(STRIKE_THROUGH_SPAN, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Concave answered 31/7, 2012 at 15:43 Comment(6)
Thanks works like a charm Specially when you need some part of TextView to have strikethrough lineMathura
+1 Solution with Spannable worked, thank you so much. You saved my day. Thanks man ;)Scarabaeus
This does not answer the question as this does not apply to RemoteViewFerrell
@Ferrell I am a bit surprised since this does work for instance in Notifications (which are remote views). I must admit I haven't tested with AppWidgets though.Concave
It does work with App Widgets (any framework span that implements ParcelableSpan should work)Delaryd
this worked with recyclerView's adapter, unlike the other answer(@ruhalde) which didn't work for it so up vote this.Inchoative
R
75

You can use this:

remoteviews.setInt(R.id.YourTextView, "setPaintFlags", Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);

Of course you can also add other flags from the android.graphics.Paint class.

Rufina answered 9/10, 2011 at 11:12 Comment(3)
Don't know how this hasn't get more votes, it perfectly answers the question. Thanks.Mullens
First it is unclear what is remoteviews , plus doesn't work for all android versions.Lexical
This is the answer we are looking for, working with app-widgets on androidTextViews are only accessible through removeViews. Accessing TextView directly is not possible at this point.Chaco
B
61

2015 Update: Folks, this is for very old versions of Android. See other answers for modern solutions!


To strike through the entire text view, you can use a specific background image to simulate the strikethrough effect:

android:background="@drawable/bg_strikethrough"

Where the bg_strikethrough drawable is a 9-patch that keeps a solid line through the middle, growing either side, with however much padding you think is reasonable. I've used one like this:

alt text

(enlarged for clarity.. 1300% !)

alt text

That is my HDPI version, so save it (the first one https://i.stack.imgur.com/nt6BK.png) as res/drawable-hdpi/bg_strikethrough.9.png and the configuration will work as so:

alt text

Brigitta answered 20/1, 2011 at 20:37 Comment(2)
and what to do if the TextView is longer than the text and only the text should be struck through?Handicapper
only for black and one line text ... @Expediency worked for me.Armilda
K
40

For doing this you can use this

 title.setPaintFlags(title.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

and for remove you can use this

 title.setPaintFlags(title.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
Kantianism answered 7/5, 2017 at 20:32 Comment(2)
how can i add strike colorMarlomarlon
@Marlomarlon this seems to only allow you to use the color of the text. If you want a different strikethrough color you'll have to try other implementation method.Syllabus
S
26

Here is an extension for all you Kotlin folks

fun TextView.showStrikeThrough(show: Boolean) {
    paintFlags =
            if (show) paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
            else paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
}

Usage

textView.showStrikeThrough(true)

Limitation

Strikethroughs can only be the same color as the text

(i.e. Red text and blue strikethrough is not possible)

Syllabus answered 2/4, 2019 at 17:19 Comment(0)
P
13

Make a drawable file, striking_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">
        <shape android:shape="line">
            <stroke android:width="1dp" android:color="@android:color/holo_red_dark" />
        </shape>
    </item>
</selector>

layout xml

 <TextView
            ....
            ....
            android:background="@drawable/striking_text"
            android:foreground="@drawable/striking_text"
            android:text="69$"
           />

If your min SDK below API level 23 just use the background or just put the background and foreground in the Textview then the android studio will show an error that says create a layout file for API >23 after that remove the android:foreground="@drawable/stricking_text" from the main layout

Output look like this: enter image description here

Polytonality answered 17/11, 2020 at 15:15 Comment(0)
B
12

It is really easy if you are using strings:

<string name="line"> Not crossed <strike> crossed </strike> </string>

And then just:

<TextView 
        ...
         android:text="@string/line"
 />
Bil answered 7/6, 2014 at 0:23 Comment(1)
@war_Hero Worked for me, doesn't render in Android Studio's renderer though. Had to actually build it to see it.Devaney
H
9

For multiline TextView you should use android.text.style.CharacterStyle like this:

SpannableString spannable = new SpannableString(text);
spannable.setSpan(new StrikethroughSpan(), 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
remoteViews.setTextViewText(R.id.itemText, spannable);
Honk answered 23/6, 2014 at 16:26 Comment(0)
G
8

Add the line below:-

TextView tv=(TextView) v.findViewById(android.R.id.text1);
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

use your reference instead of "tv"

Guillory answered 23/11, 2015 at 10:14 Comment(1)
This does not reference the question, he's asking about a RemoteViews object in an AppWidget.Fulford
T
6

try this code

textview.setText((Html.fromHtml("<strike>hello world!</strike>")));
Tedi answered 21/5, 2018 at 9:5 Comment(0)
N
3

Kotlin way

val tv = findViewById<View>(R.id.mytext) as TextView
tv.text = "This is strike-through"
tv.paintFlags = tv.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
Norvall answered 27/9, 2021 at 6:25 Comment(0)
F
2

For Lollipop and above. create a drawable

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="false">
        <shape android:shape="line">
            <stroke android:width="1dp"
                android:color="@color/onePlusRed" />
        </shape>
    </item>
</selector>

and use it as foreground.
android:foreground="@drawable/strike_through"

Freehold answered 13/3, 2019 at 11:38 Comment(1)
this will only work for single line texts as it's View dependentLetterperfect
U
2

Android resources have pretty good HTML markup support
The below HTML elements are supported:

Bold: <b>, <em>
Italic: <i>, <cite>, <dfn>
25% larger text: <big>
20% smaller text: <small>
Setting font properties: <font face=”font_family“ color=”hex_color”>. Examples of possible font families include monospace, serif, and sans_serif.
Setting a monospace font family: <tt>
Strikethrough: <s>, <strike>, <del>
Underline: <u>
Superscript: <sup>
Subscript: <sub>
Bullet points: <ul>, <li>
Line breaks: <br>
Division: <div>
CSS style: <span style=”color|background_color|text-decoration”>
Paragraphs: <p dir=”rtl | ltr” style=”…”>

Note however that it's not rendered in android studio layouts preview. Last tested on Android Studio 3.3.1

For example, the Strikethrough will look like that:

<string name="cost"><strike>$10</strike> $5 a month</string>
Unaunabated answered 3/4, 2019 at 12:24 Comment(0)
L
2

Kotlin way

averagePrice.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG

Leathern answered 25/9, 2022 at 17:53 Comment(1)
You should not set flag but add it to existing, because there can be other flags set (for antialiasing, for example)Mcnew
G
1

You Can use data binding! In XML layout just do app:strike="@{true}"

@BindingAdapter("strike")
fun bindTextView(view: TextView, strike: Boolean) {
    if (strike) {
        view.paintFlags = view.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
    } else {
        view.paintFlags = 0 or Paint.ANTI_ALIAS_FLAG
    }
}
Geist answered 6/4, 2022 at 1:48 Comment(0)
R
0

you add in :

TextView variableTv = (TextView) findViewById(R.id.yourText);

you set/add in You variable :

variableTv.setText("It's Text use Style Strike");

and then add .setPaintFlags in variableTv :

variableTv.setPaintFlags(variableTv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
Roux answered 4/4, 2017 at 8:34 Comment(0)
F
0

I tried few options but, this works best for me:

String text = "<strike><font color=\'#757575\'>Some text</font></strike>";
textview.setText(Html.fromHtml(text));

cheers

Finzer answered 16/1, 2018 at 22:37 Comment(0)
M
0

Another solution as a Kotlin extension:

var TextView.isStrikeThrough: Boolean
    get() = (paintFlags and Paint.STRIKE_THRU_TEXT_FLAG) == Paint.STRIKE_THRU_TEXT_FLAG
    set(value) {
        paintFlags = if (value) {
            paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
        } else {
            paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
        }
    }

Mcnew answered 21/5, 2023 at 11:24 Comment(0)
G
0

I created this method to use from any where within my app

static String formatSellingPrice(Context ctx, String Original_Price, String Selling_Price, boolean isUnder_Promotion) {
        String Currency_Symbol = ctx.getResources().getString(R.string.Currency_Symbol);

        if (isUnder_Promotion) {
            return String.format("<strike><font color=\"#757575\">%s %s</font></strike> %s %s", Original_Price, Currency_Symbol, Selling_Price, Currency_Symbol);
        } else {
            return Selling_Price + " " + Currency_Symbol;
        }
    }

it can be used if you have multi language and multi currency app

I call it like this:

String formated_SellingPrice = formatSellingPrice(this, Original_Price, Selling_Price, isUnder_Promotion);

then assign like this

tv_Card_Selling_Price.setText(Html.fromHtml(formated_SellingPrice));
Gearldinegearshift answered 19/4, 2024 at 14:1 Comment(0)
I
-1

I've done this on a regular (local) TextView, and it should work on the remote variety since the docs list the method as equivalent between the two:

remote_text_view.setText(Html.fromHtml("This is <del>crossed off</del>."));

Irruptive answered 7/10, 2010 at 12:55 Comment(5)
It does not work :(. I am doing this: remoteView.setTextViewText(R.id.text, Html.fromHtml("<del>" + value + "</del>"));Cowan
It might be that <del> isn't supported by Html.fromHtml(). Have you tried <strike> or <s>?Irruptive
Thanks Blrfl, but it does not work either. It seems that only a few HTML tags are suported by Html.fromHtml().Cowan
Bummer. Sorry I couldn't help.Irruptive
how can i achieve for price with strike like shopping apps for offersMarlomarlon
S
-1

I know, I am answering an old question, it might be helpful for someone else, for striking out a particular portion of TextView programmatically.

TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("Text need to be set here", TextView.BufferType.SPANNABLE);
Spannable spannable = (Spannable) textView.getText();
spannable.setSpan(new StrikethroughSpan(), 5, 8, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

So, in this example code, 5 is starting position and 8 is ending position of text need to be stricken out, so after running this code we can get the text "need" with striked out. Hope it will helpful for someone else.

Sweettalk answered 15/3, 2018 at 9:20 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.