我使用ByteArrayToImageConverter来转换来自SQL Server数据库的字节数组,转换器如下所示
public class ByteArrayToImageConverter : IValueConverter
{
public ImageSource retSource;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// ImageSource retSource = null;
if (value != null)
{
byte[] imageAsBytes = (byte[])value;
// byte[] decodedByteArray = System.Convert.FromBase64String(Encoding.UTF8.GetString(imageAsBytes, 0, imageAsBytes.Length));
// var stream = new MemoryStream(decodedByteArray);
retSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
}
return retSource;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
//return null;
throw new NotImplementedException();
}
我的观点模型如下
public class ResturentItems {
public long ID { get; set; }
public string Category { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public bool isservicecharge { get; set; }
public decimal CostPrice { get; set; }
public string Date { get; set; }
public byte[] Image { get; set; } }
public class ResturentList
{
public List<ResturentItems> Resturent { get; set; }
}
背后的网络页面代码
namespace TestProject.Views.DetailViews
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FoodTabPage : ContentPage
{
private List<ResturentItems> _foodList;
public FoodTabPage(string categoryName, List<ResturentItems>foodList)
{
InitializeComponent();
this.BackgroundImage = "background.png";
// createEventsList();
Title = categoryName;
mealsListView.ItemsSource = foodList;
_foodList = foodList;
}
private void Search(object sender, EventArgs e)
{
stackLayoutShowHide.IsVisible = !stackLayoutShowHide.IsVisible;
}
private void searchChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(e.NewTextValue))
mealsListView.ItemsSource = _foodList;
else
mealsListView.ItemsSource = _foodList.Where(i => i.Name.ToLower().Contains(e.NewTextValue.ToLower()));
}
private void listviewContacts_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var itemSelectedData = e.SelectedItem as ResturentItems;
Navigation.PushAsync(new JsonDetailsPage(itemSelectedData.ID, itemSelectedData.Image, itemSelectedData.Name, itemSelectedData.Code, itemSelectedData.Description, itemSelectedData.Price, itemSelectedData.isservicecharge, itemSelectedData.CostPrice));
//this.Content = null;
//this.BindingContext = null;
//GC.Collect(1);
}
protected override void OnDisappearing()
{
// ImagesStackLayout.Children.Clear();
GC.Collect();
// mealsListView.BindingContext = null;
// this.Content = null;
//mealsListView.ItemsSource = null;
//this.BindingContext = null;
//GC.Collect(1);
}
}
}
标准页面的XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestProject.Views.DetailViews.FoodTabPage"
xmlns:local ="clr-namespace:TestProject.Data">
<ContentPage.Resources>
<ResourceDictionary>
<local:ByteArrayToImageConverter x:Key="severityTypeImageConvertertwo"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Search" Clicked="Search"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout>
<StackLayout x:Name="stackLayoutShowHide" IsVisible="False">
<Entry Placeholder="Your text to search" TextChanged="searchChanged" TextColor="Gray" BackgroundColor="White"/>
</StackLayout>
<ListView x:Name="mealsListView" HasUnevenRows="True" ItemSelected="listviewContacts_ItemSelected" CachingStrategy="RecycleElement" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Padding="5">
<StackLayout Orientation="Horizontal" BackgroundColor="Ivory" Opacity="0.9">
<Image Source="{Binding Image,Converter={StaticResource severityTypeImageConvertertwo}}" HeightRequest="120" WidthRequest="120"/>
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}" FontSize="Medium" TextColor="Gray" FontAttributes="Bold"/>
<BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Description}" FontSize="Micro" TextColor="Gray" FontAttributes="Bold"/>
<StackLayout Orientation="Horizontal" VerticalOptions="Start" HorizontalOptions="Start">
<Label Text="$" FontSize="Micro" VerticalOptions="Start" HorizontalOptions="Start" TextColor="Gray" FontAttributes="Bold"/>
<Label Text="{Binding Price}" FontSize="Micro" TextColor="Gray" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>
<Image Source="arrowtwo.png" BackgroundColor="Transparent" WidthRequest="25" Margin="0,10,10,0"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
我通过带API调用的标签页获取内容页面数据,如下所示
public partial class FoodTabbedPage : TabbedPage
{
// List<ResturentItems> ResturentList = new List<ResturentItems>();
List<ResturentItems> ResturentList;
//SearchBar searchBar;
//Label resultsLabel;
public FoodTabbedPage()
{
// List<ResturentItems> ResturentList = new List<ResturentItems>();
InitializeComponent();
this.BackgroundImage = "Resources/drawable/background.png";
this.BackgroundColor = Color.Maroon;
Children.Add(new TabLoader());
//View.BackgroundColor = UIColor.FromPatternImage(UIImage.FromFile("Images/bg.png"));
//this.ParentView = "background.png";
// this.View.BackgroundColor = UIColor.FromPatternImage(UIImage.FromFile("your-background.png"));
//ActivityIndicator ciclenow = new ActivityIndicator();
//ciclenow.Color = Color.Green;
//ciclenow.IsRunning = true;
ActivityIndicator ai = new ActivityIndicator
{
Color = Color.Black,
IsRunning = true,
};
this.IsBusy = true;
GetJSON();
//Children.Remove(new JsonDesertNew());
//var stack = new StackLayout
//{
// Spacing = 20,
// Children = {
// new Label {Text = "Hello World!"},
// new Button {Text = "Click Me!"}
// }
//};
//ToolbarItem cartItem = new ToolbarItem();
//cartItem.Order = ToolbarItemOrder.Primary;
//cartItem.Text = "serch";
//cartItem.Command = new Command(() => Navigation.PushAsync(new SearchItemsPage()));
//ToolbarItems.Add(cartItem);
ToolbarItem serch = new ToolbarItem();
serch.Order = ToolbarItemOrder.Secondary;
serch.Text = "SERCH MORE";
serch.Command = new Command(() => Navigation.PushAsync(new SearchItemsPage()));
ToolbarItems.Add(serch);
}
public async void GetJSON()
{
var client = new System.Net.Http.HttpClient();
var response = await client.GetAsync("http://192.168.43.51/TabPageAll.php");
string contactsJson = response.Content.ReadAsStringAsync().Result;
if (response.IsSuccessStatusCode)
{
var list = JsonConvert.DeserializeObject<ResturentList>(contactsJson);
ResturentList = new List<ResturentItems>(list.Resturent);
List<string> allCategories = ResturentList.Select(x => x.Category).ToList();
allCategories = allCategories.Distinct().ToList();
foreach (var category in allCategories)
{
//Children.Remove(Children.First());
Children.Add(new FoodTabPage(category, ResturentList.Where(x => x.Category == category).ToList()));
// Children.Remove(Children.First());
}
Children.Remove(Children.First());
}
else
{
var textReader = new JsonTextReader(new StringReader(contactsJson));
dynamic responseJson = new JsonSerializer().Deserialize(textReader);
contactsJson = "Deserialized JSON error message: " + responseJson.Message;
await DisplayAlert("fail", "no Network Is Available.", "Ok");
}
}
我的问题当我在xaml列表视图中显示所有图像(与我的模型绑定)我有记忆泄漏时,每次打开列表视图时内存逐渐增长,Whast是减少memeor泄漏问题的解决方案使用转换器和列表视图(顺便说一下我使用CachingStrategy="RecycleElement"
,但它可以减少内存泄漏。如果有任何人遇到此类问题请告诉我。
ProfilerImage
ProfilerImage2
感谢您的支持。 泛