glide-xamarin-android icon indicating copy to clipboard operation
glide-xamarin-android copied to clipboard

Subclass ViewTarget

Open thaindq opened this issue 8 years ago • 7 comments

I'm trying to port this code to C# and this is what I've got so far

public class GlideImageGetter : Java.Lang.Object, Html.IImageGetter, Drawable.ICallback
{
    private Context mContext;
    private TextView mTextView;
    private HashSet<ImageGetterViewTarget> mTargets;

    public static GlideImageGetter Get(View view)
    {
        return (GlideImageGetter)view.GetTag(Resource.Id.drawable_callback_tag);
    }

    public void Clear()
    {
        GlideImageGetter prev = Get(mTextView);
        if (prev == null)
            return;

        foreach (var target in prev.mTargets)
        {
            Glide.Clear(target);
        }
    }

    public GlideImageGetter(Context context, TextView textView)
    {
        mContext = context;
        mTextView = textView;
        Clear();
        mTargets = new HashSet<ImageGetterViewTarget>();
        mTextView.SetTag(Resource.Id.drawable_callback_tag, this);
    }

    public Drawable GetDrawable(string source)
    {
        UrlDrawable urlDrawable = new UrlDrawable();

        Glide.With(mContext)
            .Load(source)
            .DiskCacheStrategy(DiskCacheStrategy.All)
            .Into(new ImageGetterViewTarget(mTextView, urlDrawable, mTargets));

        return urlDrawable;
    }

    public void InvalidateDrawable(Drawable who)
    {
        mTextView.Invalidate();
    }

    public void ScheduleDrawable(Drawable who, IRunnable what, long when) { }

    public void UnscheduleDrawable(Drawable who, IRunnable what) { }

    private class ImageGetterViewTarget : ViewTarget
    {
        private UrlDrawable mDrawable;

        public ImageGetterViewTarget(TextView view, UrlDrawable drawable, HashSet<ImageGetterViewTarget> mTargets) : base(view)
        {
            mTargets.Add(this);
            mDrawable = drawable;
        }

        public void OnResourceReady(Java.Lang.Object resource, IGlideAnimation glideAnimation)
        {
            Rect rect;
            TextView view = (TextView)View;
            GlideDrawable drawable = (GlideDrawable)resource;

            if (drawable.IntrinsicWidth > 100)
            {
                float width;
                float height;

                if (drawable.IntrinsicWidth >= view.Width)
                {
                    float downScale = (float)drawable.IntrinsicWidth / view.Width;
                    width = drawable.IntrinsicWidth / downScale;
                    height = drawable.IntrinsicHeight / downScale;
                }
                else
                {
                    float multiplier = (float)view.Width / drawable.IntrinsicWidth;
                    width = drawable.IntrinsicWidth * multiplier;
                    height = drawable.IntrinsicHeight * multiplier;
                }

                rect = new Rect(0, 0, Java.Lang.Math.Round(width), Java.Lang.Math.Round(height));
            }
            else
            {
                rect = new Rect(0, 0, drawable.IntrinsicWidth * 2, drawable.IntrinsicHeight * 2);
            }

            drawable.Bounds = rect;

            mDrawable.Bounds = rect;
            mDrawable.SetDrawable(drawable);


            if (drawable.IsAnimated)
            {
                mDrawable.SetCallback(Get(view));
                drawable.SetLoopCount(GlideDrawable.LoopForever);
                drawable.Start();
            }

            view.Text = view.Text;
            view.Invalidate();
        }        
    }
}

When I build the project, this error pops up

GlideImageGetter_ImageGetterViewTarget is not abstract and does not override abstract method onResourceReady(Object,GlideAnimation) in Target

I looked into binding interface Com.Bumptech.Glide.Request.Target.ITarget and couldn't find that abstract method but it does exist in java code. I guess the generic type Transition<? super R> transition is the cause. If so, is there any solution to this?

thaindq avatar Feb 24 '17 04:02 thaindq

Similar problem. Trying to extend SimpleTarget so I can save the image to disk, but can't override OnResourceReady and get the same error as OP when compiling.

Eplebit avatar Feb 24 '17 11:02 Eplebit

Thanks, I will look into that and will notify you.

beraybentesen avatar Feb 24 '17 12:02 beraybentesen

Same here... Would be great to derive from BasicTarget and override onResourceReady

Unless you tell me there's a better way to use Glide to set the background of a Layout

Thanks in advance!

invertedrider avatar Mar 23 '17 00:03 invertedrider

It seems that SimpleTarget and BaseTarget are abstract classes. The Xamarin binding has problems with abstract classes and methods with abstract input types. In theory it should generate something with a Java.Lang.Object as type but appearantly it doesn't. Not sure how to fix. Any suggestions?

digitaldjango avatar Apr 03 '17 15:04 digitaldjango

As @Speedrockracer said, I had to disable a few methods in Transforms file. Glide is quite complicated library compared to Picasso so I will ask to someone from Xamarin team and maybe they will recommend an intuitive idea.

beraybentesen avatar Apr 03 '17 17:04 beraybentesen

I tried to fix the binding but didn't have any success there. It is indeed very complicated. Also tried the following workaround. Very hacky and it didn't work. Wont even go into the SetResource method.. but crashes with a ClassCastException. Maybe someone here gets inspired and can make it work?

I'm trying to load the resulting bitmap in a SubsampelingScaleImageView for zooming. If someone knows a better way without using glide feel free to drop me a line.

void LoadImage() {
				Glide.With(this).Load(url).Into(new ImageLoadTarget(_postImageView, _dummyImageView));
		}

		private class ImageLoadTarget: BitmapImageViewTarget {

			SubsamplingScaleImageView _imageView;

			public ImageLoadTarget(SubsamplingScaleImageView imageView, ImageView realImageView) : base(realImageView) {
				_imageView = imageView;
			}

			protected override void SetResource(Bitmap bitmap)
			{
				_imageView.SetImage(ImageSource.InvokeBitmap(bitmap));
			}
		}

digitaldjango avatar Apr 04 '17 13:04 digitaldjango

I've updated to 3.8.0 and haven't tested yet. Could you give a chance to see that helps ?

beraybentesen avatar Jul 04 '17 01:07 beraybentesen