Android 自定义文本视图来容纳图像和文本

Android Custom text View To hold images and text

我必须完全按照 TextView 显示的方式显示文本和图像。可以使用 spannable 对象,但问题是图像正在 运行 时间从服务器下载,并且必须显示占位符直到图像被下载..

因此,我正在考虑创建扩展 ViewGroup 的自定义 TextView,但这样会有很多处理。让我知道是否还有其他最佳选择,因为我时间不够

这可以通过使用 SpannableStringImageSpan 类 来实现。可以创建 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);
        }
    }
}