Ответ 1
Да, я нашел решение. Код для подражания. Но прежде, позвольте мне немного объяснить, что я сделал.
Таким образом, определенно необходимо взять маты в наших руках, чтобы избавиться от изображения и его основных ресурсов (растровое или рисованное, однако вы хотите назвать его). По сути, это сводится к утилизации собственного объекта ImageRenderer.
Теперь нет способа получить ссылку на этот ImageRenderer из любого места, потому что для этого нужно иметь возможность вызвать Platform.GetRenderer(...). Доступ к классу "Платформа" недоступен, поскольку его область объявлена как "внутренняя".
Итак, у меня не осталось другого выбора, кроме подкласса класса Image и его (Android) Renderer и уничтожить самого Renderer изнутри (передавая "true" в качестве аргумента. Не пытайтесь использовать "false",). Внутри Renderer я зацепился за страницу (в случае TabbedPage). В большинстве ситуаций событие "Исчезновение страницы" не будет хорошо служить цели, например, когда страница все еще находится в стеке экрана, но исчезает из-за того, что другая страница рисуется на Верх. Если вы выбрали изображение (ы), чем, когда страница будет открыта (показана) еще раз, она не отобразит изображения. В этом случае мы должны подключиться к главному событию навигации "Выбранная".
Я пытался объяснить все, что мог. Остальное - надеюсь, вы сможете получить код:
Это подкласс класса в проекте PCL.
using System;
using Xamarin.Forms;
namespace ApplicationClient.CustomControls
{
public class LSImage : Image
{
}
}
Следующий код находится в проекте Droid.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Android.Util;
using Application.Droid.CustomControls;
using ApplicationClient.CustomControls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ApplicationClient.CustomControls.LSImage), typeof(LSImageRenderer))]
namespace Application.Droid.CustomControls
{
public class LSImageRenderer : ImageRenderer
{
Page page;
NavigationPage navigPage;
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
if (GetContainingViewCell(e.NewElement) != null)
{
page = GetContainingPage(e.NewElement);
if (page.Parent is TabbedPage)
{
page.Disappearing += PageContainedInTabbedPageDisapearing;
return;
}
navigPage = GetContainingNavigationPage(page);
if (navigPage != null)
navigPage.Popped += OnPagePopped;
}
else if ((page = GetContainingTabbedPage(e.NewElement)) != null)
{
page.Disappearing += PageContainedInTabbedPageDisapearing;
}
}
}
void PageContainedInTabbedPageDisapearing (object sender, EventArgs e)
{
this.Dispose(true);
page.Disappearing -= PageContainedInTabbedPageDisapearing;
}
protected override void Dispose(bool disposing)
{
Log.Info("**** LSImageRenderer *****", "Image got disposed");
base.Dispose(disposing);
}
private void OnPagePopped(object s, NavigationEventArgs e)
{
if (e.Page == page)
{
this.Dispose(true);
navigPage.Popped -= OnPagePopped;
}
}
private Page GetContainingPage(Xamarin.Forms.Element element)
{
Element parentElement = element.ParentView;
if (typeof(Page).IsAssignableFrom(parentElement.GetType()))
return (Page)parentElement;
else
return GetContainingPage(parentElement);
}
private ViewCell GetContainingViewCell(Xamarin.Forms.Element element)
{
Element parentElement = element.Parent;
if (parentElement == null)
return null;
if (typeof(ViewCell).IsAssignableFrom(parentElement.GetType()))
return (ViewCell)parentElement;
else
return GetContainingViewCell(parentElement);
}
private TabbedPage GetContainingTabbedPage(Element element)
{
Element parentElement = element.Parent;
if (parentElement == null)
return null;
if (typeof(TabbedPage).IsAssignableFrom(parentElement.GetType()))
return (TabbedPage)parentElement;
else
return GetContainingTabbedPage(parentElement);
}
private NavigationPage GetContainingNavigationPage(Element element)
{
Element parentElement = element.Parent;
if (parentElement == null)
return null;
if (typeof(NavigationPage).IsAssignableFrom(parentElement.GetType()))
return (NavigationPage)parentElement;
else
return GetContainingNavigationPage(parentElement);
}
}
}
Наконец, я изменил имя приложения в пространстве имен на "ApplicationClient" в проекте PCL и на "Application.Droid" в проекте Droid. Вы должны изменить его на свое имя приложения.
Кроме того, несколько рекурсивных методов в конце класса Renderer, я знаю, что я мог бы объединить его в один общий метод. Дело в том, что я построил один за раз, когда возникла необходимость. Так вот, как я его оставил.
Счастливое кодирование,
Авраам