I am passing an URL string of an image from a website, these images appear in a listview on the PCL project, the URL of the image passes fine to the Android Custom Renderer, but loading the image with MonoDroidToolKit fails with the following error:
Unhandled Exception:
System.ArgumentNullException: Value cannot be null. Parameter name: key
From PCL(passing attachment information):
public partial class ImageViewPage : ContentPage
{
public ImageViewPage(Attachment imageItem)
{
if (imageItem == null)
throw new ArgumentNullException();
BindingContext = imageItem;
_imageItem = imageItem.url;
InitializeComponent();
}
public string _imageItem { get; private set; }
}
In Android Custom Renderer:
[assembly: ExportRenderer(typeof(ImageViewPage),typeof(ImageViewRenderer))]
namespace BibleCodesApp.Droid
{
public class ImageViewRenderer : PageRenderer
{
global::Android.Views.View view;
ImageLoader imageLoader;
Activity activity;
ImageView imageView;
private string imageItem
{
get
{
var imageViewPage = Element as ImageViewPage;
return imageViewPage == null
? null
: imageViewPage._imageItem;
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Page>e)
{
base.OnElementChanged(e);
activity = this.Context as Activity;
view = activity.LayoutInflater.Inflate
(Resource.Layout.ImageView,this,false);
imageLoader = new ImageLoader(activity, 512);
imageView = FindViewById<ImageView>(Resource.Id.image_view);
imageLoader.DisplayImage(imageItem, imageView, -1);
}
}
}
The layout in Android:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<BibleCodesApp.Droid.ScaleImageView
android:id="@+id/image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:adjustViewBounds="true" />
</LinearLayout>
</RelativeLayout>
This is the correct solution:
[assembly: ExportRenderer(typeof(ZoomImage), typeof(ZoomImageRenderer))]
namespace WPAppTemplate.Droid { public class ZoomImageRenderer : ImageRenderer { private ZoomImage _zoomImage; private ScaleImageView _scaleImage;
protected async override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
_zoomImage = (ZoomImage)e.NewElement;
// create the scale image and set it as the native control so it's available
_scaleImage = new ScaleImageView(Context, null);
_scaleImage.ZoomImage = _zoomImage;
SetNativeControl(_scaleImage);
await LoadImage();
}
}
protected async override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == ZoomImage.AspectProperty.PropertyName
|| e.PropertyName == ZoomImage.HeightProperty.PropertyName
|| e.PropertyName == ZoomImage.WidthProperty.PropertyName)
{
_scaleImage.ZoomToAspect();
}
else if (e.PropertyName == ZoomImage.SourceProperty.PropertyName)
{
await LoadImage();
_scaleImage.ZoomToAspect();
}
else if (e.PropertyName == ZoomImage.CurrentZoomProperty.PropertyName)
{
_scaleImage.ZoomFromCurrentZoom();
}
else if (e.PropertyName == ZoomImage.MaxZoomProperty.PropertyName)
{
_scaleImage.UpdateMaxScaleFromZoomImage();
}
else if (e.PropertyName == ZoomImage.MinZoomProperty.PropertyName)
{
_scaleImage.UpdateMinScaleFromZoomImage();
}
}
private async Task LoadImage()
{
var image = await (new ImageLoaderSourceHandler()).LoadImageAsync(_zoomImage.Source, Context);
try
{
if (image != null && image.ByteCount > 0)
_scaleImage.SetImageBitmap(image);
}
catch (Exception e)
{
// catch an image loading failure
Console.WriteLine($"Unable to load bitmap. Exception: {e.Message}");
}
}
}