为啥将 ImageSpan 添加到 Snackbar 的操作文本在 Android 设备 SDK 级别 26 上有效,但在 SDK 级别 25 上无效?

Posted

技术标签:

【中文标题】为啥将 ImageSpan 添加到 Snackbar 的操作文本在 Android 设备 SDK 级别 26 上有效,但在 SDK 级别 25 上无效?【英文标题】:Why does adding an ImageSpan to a Snackbar's action text work on Android devices SDK level 26 but not on SDK level 25?为什么将 ImageSpan 添加到 Snackbar 的操作文本在 Android 设备 SDK 级别 26 上有效,但在 SDK 级别 25 上无效? 【发布时间】:2020-10-30 08:23:44 【问题描述】:

我想显示Snackbar 并使用图像而不是文本来执行操作。

我使用以下代码:

    val imageSpan = ImageSpan(this, R.drawable.star)
    val builder = SpannableStringBuilder(" ")
    builder.setSpan(
        imageSpan,
        0,
        1,
        SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE
    )
    Snackbar.make(findViewById(R.id.container), "Hello Snackbar", Snackbar.LENGTH_INDEFINITE)
        .setAction(builder) .show()

drawable_star 是矢量图形资源,但png 也是如此。

在 26 级及以上的 android 设备上,这会产生:

正如预期的那样,而在设备 lvl 25 上,图像不可见:

有人知道这是什么原因吗?是否有解决方法?

PS:你可以在这里查看我的测试项目:https://github.com/fmweigl/SpannableTest

【问题讨论】:

【参考方案1】:

这是由于 Oreo 之前的版本中存在 textAllCaps 错误。 Button 的默认样式将把该属性设置为 true,这只会导致 Button 的文本全部转换为大写。该转换是使用平台 AllCapsTransformationMethod 类完成的,在 Nougat 7.1 及更低版本上,它会将所有内容都视为平面 Strings,基本上剥离了您设置的任何格式范围。

解决方法是关闭该属性,并在代码中处理您自己可能需要的任何大写转换。 Snackbar 提供snackbarButtonStyle 属性作为设置Button 动作样式的方法,我们可以创建一个简单的样式来修改该值。例如,来自您的styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="snackbarButtonStyle">@style/NoCapsButton</item>>
</style>

<style name="NoCapsButton" parent="Widget.AppCompat.Button">
    <item name="textAllCaps">false</item>
</style>

(如果您使用的是 Material Components 主题,则 NoCapsButtonparent 应改为 Widget.MaterialComponents.Button.TextButton.Snackbar。)


在这种特定情况下,这就是您需要做的所有事情,因为没有要转换的文本。

【讨论】:

以上是关于为啥将 ImageSpan 添加到 Snackbar 的操作文本在 Android 设备 SDK 级别 26 上有效,但在 SDK 级别 25 上无效?的主要内容,如果未能解决你的问题,请参考以下文章

文本与 EditText 中的 ImageSpan 混淆

学到了!原来 ImageSpan 还可以这样加载网络图...

好玩系列:听说你的ImageSpan没能动起来?

Android ImageSpan与TextView中的text居中对齐问题解决(无论TextView设置行距与否)

自定义 Spannable = ImageSpan + BackgroundColorSpan + ClickableSpan

加载数据后 Recyclerview 项目高度更改