ImageSpan 不适用于 Android 5
ImageSpan not working on Android 5
我的这个函数在 Android 4.4.1 上运行良好,但在 5.0+ 上运行不正常。
public static SpannableStringBuilder prependImage(Drawable drawable, String text) {
SpannableStringBuilder builder = new SpannableStringBuilder(" " + text);
builder.setSpan(new ImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return builder;
}
我是这样使用的:
class MyButton extends Button {
// ... snip ...
setText(
prependImage(
getDrawable(imageResource, color),
getContext().getString(stringResource)),
BufferType.SPANNABLE);
这是上面提到的 getDrawable()
方法:
private Drawable getDrawable(int resource, int color) {
final Resources resources = getContext().getResources();
Drawable drawable = resources.getDrawable(resource);
if (drawable != null) {
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
return drawable;
}
我调试的时候好像一切都成功了,就是画不出图。知道我可能做错了什么吗?
也许你需要检查那个Drawable对象的内容,你使用getDrawable()来获取Drawable对象,但是API定义似乎与你的调用参数不匹配。
For Android 5.0+
Drawable getDrawable(int id) This method was deprecated in API level
22. Use getDrawable(int, Theme) instead.
Drawable getDrawable(int id, Resources.Theme theme) Return a drawable
object associated with a particular resource ID and styled for the
specified theme.
第二个参数看起来像是主题,而不是颜色。对吗?
试试这个
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getResources().getDrawable(R.drawable.your_drawable, getTheme());
} else {
getResources().
getDrawable(R.drawable.your_drawable);
}
您与使用 Spannables 相关的代码没有问题。您可以通过为 TextView 设置文本来检查它。
问题出在material Android 5.0 的按钮设计中。
<style name="Widget.Material.Button">
<item name="background">@drawable/btn_default_material</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">88dip</item>
<item name="stateListAnimator">@anim/button_state_list_anim_material</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
有两种解决方法。
第一个是使用 TextView 作为您的按钮,并使用带有图像的 setText。
对于另一个(可能更正确),您需要通过以下方式扩展按钮样式 (Widget.Material.Button
):
<style name="BtnStyle" parent="android:Widget.Material.Button">
<item name="android:textAppearance">@null</item>
</style>
然后在你的布局中:
<Button
android:id="@+id/test2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test"
style="@style/BtnStyle"/>
完成后,您应该会在按钮中看到图像。
不要忘记对于低于 5.0 的 Android 版本你也应该创建 BtnStyle
,但是在其他资源目录中(res/values-v14/style.xml)。
默认情况下,在 Material 中,按钮的样式设置为全部大写显示文本。但是,用于大写的 AllCapsTransformationMethod 中存在一个错误,导致它丢弃 Spannable 数据。
您可以通过在按钮上指定 android:textAllCaps="false" 来覆盖默认按钮样式并禁用全部大写。
<Button
...
android:textAllCaps="false" />
看看
需要注意的一点是,可绘制矢量不起作用,您必须拥有一个 png 或 jpeg 可绘制对象,或者改为传递给 ImageSpan 位图
我的这个函数在 Android 4.4.1 上运行良好,但在 5.0+ 上运行不正常。
public static SpannableStringBuilder prependImage(Drawable drawable, String text) {
SpannableStringBuilder builder = new SpannableStringBuilder(" " + text);
builder.setSpan(new ImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return builder;
}
我是这样使用的:
class MyButton extends Button {
// ... snip ...
setText(
prependImage(
getDrawable(imageResource, color),
getContext().getString(stringResource)),
BufferType.SPANNABLE);
这是上面提到的 getDrawable()
方法:
private Drawable getDrawable(int resource, int color) {
final Resources resources = getContext().getResources();
Drawable drawable = resources.getDrawable(resource);
if (drawable != null) {
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
return drawable;
}
我调试的时候好像一切都成功了,就是画不出图。知道我可能做错了什么吗?
也许你需要检查那个Drawable对象的内容,你使用getDrawable()来获取Drawable对象,但是API定义似乎与你的调用参数不匹配。
For Android 5.0+
Drawable getDrawable(int id) This method was deprecated in API level 22. Use getDrawable(int, Theme) instead.
Drawable getDrawable(int id, Resources.Theme theme) Return a drawable object associated with a particular resource ID and styled for the specified theme.
第二个参数看起来像是主题,而不是颜色。对吗?
试试这个
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getResources().getDrawable(R.drawable.your_drawable, getTheme());
} else {
getResources().
getDrawable(R.drawable.your_drawable);
}
您与使用 Spannables 相关的代码没有问题。您可以通过为 TextView 设置文本来检查它。
问题出在material Android 5.0 的按钮设计中。
<style name="Widget.Material.Button">
<item name="background">@drawable/btn_default_material</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">88dip</item>
<item name="stateListAnimator">@anim/button_state_list_anim_material</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
有两种解决方法。
第一个是使用 TextView 作为您的按钮,并使用带有图像的 setText。
对于另一个(可能更正确),您需要通过以下方式扩展按钮样式 (Widget.Material.Button
):
<style name="BtnStyle" parent="android:Widget.Material.Button">
<item name="android:textAppearance">@null</item>
</style>
然后在你的布局中:
<Button
android:id="@+id/test2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test"
style="@style/BtnStyle"/>
完成后,您应该会在按钮中看到图像。
不要忘记对于低于 5.0 的 Android 版本你也应该创建 BtnStyle
,但是在其他资源目录中(res/values-v14/style.xml)。
默认情况下,在 Material 中,按钮的样式设置为全部大写显示文本。但是,用于大写的 AllCapsTransformationMethod 中存在一个错误,导致它丢弃 Spannable 数据。
您可以通过在按钮上指定 android:textAllCaps="false" 来覆盖默认按钮样式并禁用全部大写。
<Button
...
android:textAllCaps="false" />
看看
需要注意的一点是,可绘制矢量不起作用,您必须拥有一个 png 或 jpeg 可绘制对象,或者改为传递给 ImageSpan 位图