有没有一种简单的方法在应用程序小部件中添加删除线?

162
我想知道在Android应用小部件中是否有一种简单的方法来划掉文本。在普通活动中,这相当容易,使用textview flags:
textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

但是因为在应用程序小部件中,我只能使用remoteviews... 我不知道这是否可能。

有人知道关于这个的一些信息吗?

谢谢!


如果你像我一样想要一个“仅限 XML”的解决方案,请参考:https://dev59.com/62gv5IYBdhLWcg3wFsyl#49062515 - Jiyeh
21个回答

215

要在TextView中以编程方式完成此操作,在其他视图中未经测试 >>

TextView tv = (TextView) findViewById(R.id.mytext);
tv.setText("This is strike-thru");
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

14
对于应用小部件来说,这是不可能的。它们只能使用RemoteViews,并且没有方法可以读取绘制标志。 - Ridcully

88

有一种编程方式看起来比Paint方式更加正式,可以这样做:

不要像下面这样做:

tv.setText(s);

执行:

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);

谢谢,非常好用。特别是当你需要TextView的某些部分有删除线时。 - Diljeet
+1使用Spannable的解决方案很好用,非常感谢。你救了我的一天。谢谢,伙计 ;) - Simon Dorociak
这并没有回答问题,因为这不适用于“RemoteView”。 - Alex.F
@Alex.F 我有点惊讶,因为这在通知中是可以工作的(它们是远程视图)。不过我必须承认我还没有在 AppWidgets 中进行测试。 - BoD
1
它可以与应用程序小部件一起使用(任何实现ParcelableSpan的框架都应该可以工作)。 - Karsten
这个方法对于recyclerView的适配器是有效的,而其他答案(@ruhalde)却无法解决该问题,因此请给这个方法点赞。 - M. Erfan Mowlaei

75

您可以使用以下方法:

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

当然,您还可以从android.graphics.Paint类中添加其他标志。


8
不知道为什么这条评论没有得到更多的赞,它完美地回答了问题。谢谢。 - James Cross
4
首先,"remoteviews" 的含义不太清晰,并且它并不适用于所有版本的安卓系统。 - akshat tailang
这就是我们正在寻找的答案,在Android应用小部件上工作时,TextView只能通过removeViews访问。目前无法直接访问TextView。 - endevour

61

2015 年更新: 各位,这是针对非常旧版本的 Android。请查看其他答案以获取现代解决方案!


要将整个文本视图划掉,您可以使用特定的背景图像来模拟删除线效果:

android:background="@drawable/bg_strikethrough"

bg_strikethrough可绘制对象是一个9-patch图像,它通过中间保持一条实线,在两侧增长,具有您认为合理的任意填充。我使用了像这样的一个:

alt text

(已放大以获得更清晰的效果.. 1300%!)

alt text

这是我的HDPI版本,因此请将其保存(第一个图片 http://i.stack.imgur.com/nt6BK.png)为 res/drawable-hdpi/bg_strikethrough.9.png,配置将如下所示:

alt text


如果TextView的文本比较长,只有文本部分需要添加删除线,应该怎么做? - maysi
只适用于黑色和单行文本...@ruhalde对我有用。 - ahmed_khan_89

40

为了做到这一点,您可以使用此方法

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

如果您想要删除,可以使用以下方式:

 title.setPaintFlags(title.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));

1
如何添加删除线颜色 - Harsha
@Harsha 这似乎只允许您使用文本的颜色。如果您想要不同的删除线颜色,您将不得不尝试其他实现方法。 - Michael

26

这里有一个扩展,适用于所有使用 Kotlin 的人

fun TextView.showStrikeThrough(show: Boolean) {
    paintFlags =
            if (show) paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
            else paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
}
使用方法
textView.showStrikeThrough(true)

限制

删除线只能与文本颜色相同。

(例如,红色文本和蓝色删除线是不可能的)


11

如果您正在使用字符串,那么这真的很容易:

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

然后只需要:

<TextView 
        ...
         android:text="@string/line"
 />

5
对我有用,但在Android Studio的渲染器中无法显示。必须实际构建才能看到它。 - Mic Fok

10
创建一个可绘制文件,名为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>

布局 XML

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

如果您的min SDK低于API级别23,只需使用background,或者将background和foreground放在Textview中,然后Android Studio将显示一个错误,提示为API>23创建布局文件,然后从主布局中删除android:foreground="@drawable/stricking_text"

输出如下图所示: enter image description here


9

对于多行的TextView,您应该像这样使用android.text.style.CharacterStyle:

SpannableString spannable = new SpannableString(text);
spannable.setSpan(new StrikethroughSpan(), 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
remoteViews.setTextViewText(R.id.itemText, spannable);

8
添加以下行:
TextView tv=(TextView) v.findViewById(android.R.id.text1);
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);

使用您的参考资料代替“电视”


1
这并不涉及到问题本身,他在询问一个AppWidget中的RemoteViews对象。 - Matthew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接