Android 自定义文本视图来容纳图像和文本
Android Custom text View To hold images and text
我必须完全按照 TextView 显示的方式显示文本和图像。可以使用 spannable 对象,但问题是图像正在 运行 时间从服务器下载,并且必须显示占位符直到图像被下载..
因此,我正在考虑创建扩展 ViewGroup 的自定义 TextView,但这样会有很多处理。让我知道是否还有其他最佳选择,因为我时间不够
这可以通过使用 SpannableString
和 ImageSpan
类 来实现。可以创建 SpannableString
的实例,并可以将其设置为 TeaxtView
.
SpannableString
的实例可以包含文本和图像的组合。这是我能找到的一个简单示例:
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textview);
SpannableString ss = new SpannableString("abc");
Drawable d = getResources().getDrawable(R.drawable.icon32);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, 0, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(ss);
}
也看看这个link
我认为实现此目的的最简单方法是创建一个自定义 TextView,在内部使用 Html.fromHtml()
添加图像和文本。然后,您可以将占位符输入它,当图像加载时,您只需使用新图像进行更新。您几乎不需要处理任何事情。
您传递给 TextView 的内容可能是这样的:
CustomTextView(String text, List<...> plceholders)
文本包含用于放置图像的字符串占位符,例如“{img} test message {img}
”,然后简单搜索并用 <img>
标签替换 {img}
足够。
您可以在网上找到大量关于 Html.fromHtml()
的示例。
此外,N-JOY 的 Spannable String 解决方案也可以。
这是我实施的解决方案。
Spanned spanned = null;
String messageCustomized = "<img src ='"+ WebConstant.IMAGE_BASE_URL +
part +"'/>";//WebConstant.IMAGE_BASE_URL + part;
Spanned span = Html.fromHtml(messageCustomized, new
URLImageParser(sentMessagesViewHolder.tvMessage, context), null);
if (spanned!=null) {
spanned = (Spanned) TextUtils.concat(spanned, span);
}else spanned= span;
if (spanned!=null) {
txtView.setText(spanned);
}
图片Getter
public class URLImageParser implements ImageGetter {
Context context;
View container;
private int imageSize = 20;
private int imageSizeDisplaySize = 20;
URLDrawable urlDrawable = null;
public URLImageParser(View container, Context context) {
this.context = context;
this.container = container;
imageSize = Utility.convertDpTopPixels(context, 20);
imageSizeDisplaySize = Utility.convertDpTopPixels(context, 35);
}
@Override
public Drawable getDrawable(final String url) {
String[] arr = url.split("/");
final String fileName = arr[arr.length - 1];
urlDrawable = new URLDrawable();
Drawable drawable = null;
if (Build.VERSION.SDK_INT >= 21)
drawable =
context.getDrawable(R.drawable.profile_main_placeholder);
else
drawable = context.getResources().getDrawable(R.drawable.profile_main_placeholder);
drawable.setBounds(0, 0, 0 + imageSize, 0 + imageSize);
urlDrawable.drawable = drawable;
Bitmap bitmap = null;
bitmap = ImageUtility.getImageFromSDCard(fileName);
if (bitmap != null) { // the bitmap is available
bitmap = RoundedImageView.getCroppedBitmap(bitmap, imageSize, imageSize, imageSize);
drawable = new BitmapDrawable(context.getResources(), bitmap);//ImageUtility.bitmapToDrawable(context,resource);
drawable.setBounds(0, 0, 0 + imageSize, 0 + imageSize); //set the correct bound according to the result from HTTP call
URLImageParser.this.urlDrawable.drawable = drawable;
} else
Glide.with(context)
.load(url)
.asBitmap()
.transform(new CircleTransform(context))
.override(imageSizeDisplaySize, imageSizeDisplaySize)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// you can do something with loaded bitmap here
// .....
Drawable drawable = new BitmapDrawable(context.getResources(), resource);//ImageUtility.bitmapToDrawable(context,resource);
drawable.setBounds(0, 0, 0 + imageSize, 0 + imageSize); //set the correct bound according to the result from HTTP call
URLImageParser.this.urlDrawable.drawable = drawable;
URLImageParser.this.container.invalidate();
ImageUtility.saveImageToSDCard(resource, fileName);
}
});
return urlDrawable.drawable; //return reference to URLDrawable where We will change with actual image from the src tag
//}
}
}
自定义位图可绘制对象
public class URLDrawable extends BitmapDrawable {
// the drawable that you need to set, you could set the initial drawing
// with the loading image if you need to
protected Drawable drawable;
@Override
public void draw(Canvas canvas) {
// override the draw to facilitate refresh function later
if(drawable != null) {
drawable.draw(canvas);
}
}
}
我必须完全按照 TextView 显示的方式显示文本和图像。可以使用 spannable 对象,但问题是图像正在 运行 时间从服务器下载,并且必须显示占位符直到图像被下载..
因此,我正在考虑创建扩展 ViewGroup 的自定义 TextView,但这样会有很多处理。让我知道是否还有其他最佳选择,因为我时间不够
这可以通过使用 SpannableString
和 ImageSpan
类 来实现。可以创建 SpannableString
的实例,并可以将其设置为 TeaxtView
.
SpannableString
的实例可以包含文本和图像的组合。这是我能找到的一个简单示例:
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textview);
SpannableString ss = new SpannableString("abc");
Drawable d = getResources().getDrawable(R.drawable.icon32);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, 0, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(ss);
}
也看看这个link
我认为实现此目的的最简单方法是创建一个自定义 TextView,在内部使用 Html.fromHtml()
添加图像和文本。然后,您可以将占位符输入它,当图像加载时,您只需使用新图像进行更新。您几乎不需要处理任何事情。
您传递给 TextView 的内容可能是这样的:
CustomTextView(String text, List<...> plceholders)
文本包含用于放置图像的字符串占位符,例如“{img} test message {img}
”,然后简单搜索并用 <img>
标签替换 {img}
足够。
您可以在网上找到大量关于 Html.fromHtml()
的示例。
此外,N-JOY 的 Spannable String 解决方案也可以。
这是我实施的解决方案。
Spanned spanned = null;
String messageCustomized = "<img src ='"+ WebConstant.IMAGE_BASE_URL +
part +"'/>";//WebConstant.IMAGE_BASE_URL + part;
Spanned span = Html.fromHtml(messageCustomized, new
URLImageParser(sentMessagesViewHolder.tvMessage, context), null);
if (spanned!=null) {
spanned = (Spanned) TextUtils.concat(spanned, span);
}else spanned= span;
if (spanned!=null) {
txtView.setText(spanned);
}
图片Getter
public class URLImageParser implements ImageGetter {
Context context;
View container;
private int imageSize = 20;
private int imageSizeDisplaySize = 20;
URLDrawable urlDrawable = null;
public URLImageParser(View container, Context context) {
this.context = context;
this.container = container;
imageSize = Utility.convertDpTopPixels(context, 20);
imageSizeDisplaySize = Utility.convertDpTopPixels(context, 35);
}
@Override
public Drawable getDrawable(final String url) {
String[] arr = url.split("/");
final String fileName = arr[arr.length - 1];
urlDrawable = new URLDrawable();
Drawable drawable = null;
if (Build.VERSION.SDK_INT >= 21)
drawable =
context.getDrawable(R.drawable.profile_main_placeholder);
else
drawable = context.getResources().getDrawable(R.drawable.profile_main_placeholder);
drawable.setBounds(0, 0, 0 + imageSize, 0 + imageSize);
urlDrawable.drawable = drawable;
Bitmap bitmap = null;
bitmap = ImageUtility.getImageFromSDCard(fileName);
if (bitmap != null) { // the bitmap is available
bitmap = RoundedImageView.getCroppedBitmap(bitmap, imageSize, imageSize, imageSize);
drawable = new BitmapDrawable(context.getResources(), bitmap);//ImageUtility.bitmapToDrawable(context,resource);
drawable.setBounds(0, 0, 0 + imageSize, 0 + imageSize); //set the correct bound according to the result from HTTP call
URLImageParser.this.urlDrawable.drawable = drawable;
} else
Glide.with(context)
.load(url)
.asBitmap()
.transform(new CircleTransform(context))
.override(imageSizeDisplaySize, imageSizeDisplaySize)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// you can do something with loaded bitmap here
// .....
Drawable drawable = new BitmapDrawable(context.getResources(), resource);//ImageUtility.bitmapToDrawable(context,resource);
drawable.setBounds(0, 0, 0 + imageSize, 0 + imageSize); //set the correct bound according to the result from HTTP call
URLImageParser.this.urlDrawable.drawable = drawable;
URLImageParser.this.container.invalidate();
ImageUtility.saveImageToSDCard(resource, fileName);
}
});
return urlDrawable.drawable; //return reference to URLDrawable where We will change with actual image from the src tag
//}
}
}
自定义位图可绘制对象
public class URLDrawable extends BitmapDrawable {
// the drawable that you need to set, you could set the initial drawing
// with the loading image if you need to
protected Drawable drawable;
@Override
public void draw(Canvas canvas) {
// override the draw to facilitate refresh function later
if(drawable != null) {
drawable.draw(canvas);
}
}
}