是的,我找到了解決方案。要遵循的代碼。但在此之前,讓我稍微解釋我所做的一切。
因此,肯定需要在我們自己的手中使用maters來處理圖像及其底層資源(位圖或可繪製,但是您想稱之爲)。基本上,它歸結爲處理原生的'ImageRenderer'對象。
現在,無法從任何地方獲取對該ImageRenderer的引用,因爲要這樣做,需要能夠調用Platform.GetRenderer(...)。由於其範圍被聲明爲「內部」,因此無法訪問「平臺」類。
因此,除了爲Image類和它的(Android)Renderer子類並從內部銷燬這個Renderer本身(作爲參數傳遞'true')之外,我沒有別的選擇。不要嘗試'false 「)。在渲染器內部,我掛鉤頁面消失(如果是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);
}
}
}
最後,我在PCL項目改變了應用程序的名稱的命名空間「ApplicationClient」和Droid的項目爲「Application.Droid」。您應該將其更改爲您的應用程序名稱。
此外,Renderer類末尾的幾個遞歸方法,我知道我可以將它組合成一個Generic方法。事情是,當我需要時,我一次一個建立一個。所以,我就是這樣離開它的。
快樂編碼,
Avrohom
什麼的4K PNG的位圖大小? PNG存儲在內存中而不壓縮。當轉換爲位圖時,可以創建一個超過1GB數據的4K PNG。 另外,是的,你真的需要檢查位圖是否處置。也許答案是,不,他們不是。 – Frank 2014-09-12 11:35:03
我目前使用的PNG被定義爲512 x 512. – Avrohom 2014-09-12 12:02:01
因此,4kB PNG需要512 x 512 x 32位= 1MB的RAM來存儲/顯示。所以你很可能不會處置它們。 – Frank 2014-09-12 12:04:33