androiduniversal-image-loader

How to listen for clicks on drawn images in Html.ImageGetter class


I have an Html.ImageGetter class that I am using with Universal Image Loader to load images in <img> tags contains in a html json file I fetch online.

The images are loading quite alright but on smaller devices the images are shrinked to match the width of the device hence making some images too small to see the content.

my purpose was to set a click listener on the images and display a zoom dialog where the user can see the full size of the image. Currently, I am finding it difficult to listen for clicks.

This is my ImageGetter class

public class UILImageGetter implements Html.ImageGetter{
    Context c;
    TextView container;
    UrlImageDownloader urlDrawable;


    public UILImageGetter(View textView, Context context) {
        this.c = context;
        this.container = (TextView) textView;
    }

    @Override
    public Drawable getDrawable(String source) {

        urlDrawable = new UrlImageDownloader(c.getResources(), source);

        if (Build.VERSION.SDK_INT >= 21) {
        urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb,null);
        } else {
            urlDrawable.mDrawable = c.getResources().getDrawable(R.drawable.default_thumb);
        }
        ImageLoader.getInstance().loadImage(source, new SimpleListener(urlDrawable));
        return urlDrawable;
    }

    private class SimpleListener extends SimpleImageLoadingListener {
        UrlImageDownloader mUrlImageDownloader;


        public SimpleListener(UrlImageDownloader downloader) {
            super();
            mUrlImageDownloader= downloader;
        }

        @Override
        public void onLoadingStarted(String imageUri, View view) {
            Log.d("DEBUG", "onLoadingStarted called");
            //spinner.setVisibility(View.VISIBLE);

        }

        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            //spinner.setVisibility(View.GONE);

            int width = loadedImage.getWidth();
            int height = loadedImage.getHeight();

            int newWidth = width;
            int newHeight = height;

            if (width > container.getWidth()) {
                newWidth = container.getWidth();
                newHeight = (newWidth * height) / width;
            }

            if (view != null) {
                container.getLayoutParams().width = newWidth;
                container.getLayoutParams().height = newHeight;
            }

            Drawable result = new BitmapDrawable(c.getResources(), loadedImage);
            result.setBounds(0, 0, newWidth, newHeight);

            mUrlImageDownloader.setBounds(1, 1, newWidth, newHeight);
            mUrlImageDownloader.mDrawable = result;
            container.invalidate();

            container.setText(container.getText());

            if (view != null) {
                //Don't know if this is the right place to listener for clicks but it ain't working
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.d("TheImage", "Image Clicked");
                    }
                });
            }

        }

        @Override
        public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
            String message = null;
            switch (failReason.getType()) {
                case IO_ERROR:
                    message = "Input/Output error";
                    break;
                case DECODING_ERROR:
                    message = "Image can't be decoded";
                    break;
                case NETWORK_DENIED:
                    message = "Downloads are denied";
                    break;
                case OUT_OF_MEMORY:
                    message = "Out Of Memory error";
                    break;
                case UNKNOWN:
                    message = "Unknown error";
                    break;
            }


//            Toast.makeText(view.getContext(), message, Toast.LENGTH_SHORT).show();
            Log.w("UILImageGetter", message);

            //spinner.setVisibility(View.GONE);
        }



    }

    private class UrlImageDownloader extends BitmapDrawable {
        public  Drawable mDrawable;

        public UrlImageDownloader(Resources resources, String filepath) {
            super(resources, filepath);
            mDrawable = new BitmapDrawable(resources, filepath);
        }

        @Override
        public void draw(Canvas canvas) {
            if (mDrawable != null) {
                mDrawable.draw(canvas);
            }
        }
    }
}

Please, could you help me with this?


Solution

  • The images themselves are not clickable, but you can wrap them in custom URLSpans and listen for clicks from those URLSpans and then run your action.

    Parse the HTML using Html.fromHtml(...) and do:

    Spannable html = (Spannable) Html.fromHtml(...);
    for (ImageSpan span : html.getSpans(0, html.length(), ImageSpan.class)) {
        int flags = html.getSpanFlags(span);
        int start = html.getSpanStart(span);
        int end = html.getSpanEnd(span);
        
        html.setSpan(new URLSpan(span.getSource()) {
            @Override public void onClick(View v) {
                /* handle click here */
            }
        }, start, end, flags);
    }
    textView.setText(html);
    textView.setMovementMethod(LinkMovementMethod.getInstance());