Skip to content

Instantly share code, notes, and snippets.

@softlion
Created August 26, 2015 14:20
Show Gist options
  • Save softlion/1df832a1711fb38f00a2 to your computer and use it in GitHub Desktop.
Save softlion/1df832a1711fb38f00a2 to your computer and use it in GitHub Desktop.
Fix for XamSvg in a button on Xamarin Android Forms
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:demo="clr-namespace:XamSvg.Demo;assembly=XamSvg.Demo"
x:Class="XamSvg.Demo.MainPage"
BackgroundColor="#E08080"
Title="XamSvg Demo">
<demo:MyButton x:Name="TestButton" Text="TestText" />
</ContentPage>
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
//FileImageSource is sealed. We can currently not derive SvgImageSource from FileImageSource.
var svg = new SvgImageSource { Svg = "res:images.hand", HeightRequest = 20, ColorMapping = "ffffff=00ff00" };
var image = svg.Image;
TestButton.Image = svg.Image;
}
}
public class MyButton : Button
{
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using XamSvg.Demo;
using XamSvg.Demo.Droid;
using Button = Xamarin.Forms.Button;
[assembly: ExportRenderer(typeof(MyButton), typeof(MyButtonRenderer))]
namespace XamSvg.Demo.Droid
{
class MyButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
UpdateBitmap();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == Button.ImageProperty.PropertyName)
UpdateBitmap();
else
base.OnElementPropertyChanged(sender, e);
}
private void UpdateBitmap()
{
if (Element.Image != null && !string.IsNullOrEmpty(Element.Image.File))
{
var imagefile = Element.Image.File;
Drawable drawable;
if (imagefile.StartsWith("res:"))
{
var strings = imagefile.Split(',');
var file = strings[0];
var cm = strings[1];
drawable = SvgFactory.GetDrawableFromEmbeddedResource(file, SvgColorMapperFactory.FromString(cm));
}
else
drawable = Context.Resources.GetDrawable(imagefile);
Control.SetCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
if (drawable != null)
drawable.Dispose();
}
else
Control.SetCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
}
}
}
@rraallvv
Copy link

rraallvv commented Feb 1, 2018

@softlion thanks, I managed to make it load files from the filesystem, I'm positioning it here so maybe someone could improve on this to make it work with XamSvg.

public class ImageButtonRenderer : ButtonRenderer
{
	Context context;

	public ImageButtonRenderer(Context context) : base(context)
	{
		this.context = context;
	}

	protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
	{
		if (e.NewElement.Image != null && !string.IsNullOrEmpty(Element.Image.File))
		{
			var image = e.NewElement.Image;
			e.NewElement.Image = null;
			base.OnElementChanged(e);
			e.NewElement.Image = image;
		}
		else
			base.OnElementChanged(e);

		int padding = (int)Math.Round(((ImageButton)Element).Padding);
		Control.SetPadding(padding, padding, padding, padding);
		Control.SetBackground(null);
		Element.WidthRequest = Element.HeightRequest;
	}

	protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
	{
		if (e.PropertyName == Button.ImageProperty.PropertyName)
			UpdateBitmap();
		else
			base.OnElementPropertyChanged(sender, e);
	}

	private void UpdateBitmap()
	{
		if (Control == null)
			return;
		
		if (Element.Image != null && !string.IsNullOrEmpty(Element.Image.File))
		{
			var imagefile = Element.Image.File;

			var scale = context.Resources.DisplayMetrics.ScaledDensity;

			Drawable drawable = Drawable.CreateFromPath(imagefile);
			drawable.SetBounds(0, 0, (int)(scale * drawable.IntrinsicWidth), (int)(scale * drawable.IntrinsicHeight));

			Control.SetCompoundDrawables(drawable, null, null, null);

			if (drawable != null)
				drawable.Dispose();
		}
		else
			Control.SetCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment