Search code examples
androidtextviewemojiviewgroup

Android Custom text View To hold images and text


enter image description here

I have to show text and images exactly as TextView holds. spannable object can be used but the problem is images are being downloaded from server at run time and have to display placeholder till images are downloaded..

So I am thinking of creating Custom TextView which extends a ViewGroup but then there would be a lot of handling. let me know if there is another best option available because I have shortage of time


Solution

  • Here is the solution I implemented.

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

    Image 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
    //}
    }
    }
    

    Custom Bitmap Drawable

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