[英]Xamarin: UITableView cell images not showing in cell when fetched from the web until the cell is clicked
我想在UITableView
控制器的GetCell
方法中顯示從URL到cell.ImageView.Image
變量的圖像。 由於某些原因,僅當我單擊單元格時才顯示圖像。 它正在獲取圖像,但是該單元未更新。 數據是一個ObservableCollection
,所以我不確定我缺少什么。 我需要顯式調用任何方法嗎?
public class PasswordGroupsDataSource : UITableViewDataSource
{
const string PlaceholderImagePath = "Placeholder.jpg";
UIImage PlaceholderImage { get; set; }
PasswordsViewController Controller { get; set; }
List<Password> Apps;
public ObservableCollection<PasswordGroup> Groups { get; set; }
public PasswordGroupsDataSource(ObservableCollection<PasswordGroup> groups, PasswordsViewController controller, List<Password> passwords)
{
Controller = controller;
Apps = passwords;
PlaceholderImage = UIImage.FromFile("Images/Placeholder.png");
if (groups == null)
{
throw new ArgumentNullException("groups");
}
Groups = groups;
groups.CollectionChanged += HandleAppsCollectionChanged;
// If either a download fails or the image we download is corrupt, ignore the problem.
TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e)
{
e.SetObserved();
};
}
void HandleAppsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Whenever the Items change, reload the data.
Controller.TableView.ReloadData();
}
public Password GetPerson(NSIndexPath indexPath)
{
try
{
var personGroup = Groups[indexPath.Section];
return personGroup.People[indexPath.Row];
}
catch (Exception exc)
{
Console.WriteLine("Error in GetPerson: " + exc.Message);
//Occasionally we get an index out of range here
return null;
}
}
public override string TitleForHeader(UITableView tableView, nint section)
{
return Groups[(int)section].Title;
}
public override string[] SectionIndexTitles(UITableView tableView)
{
return Groups.Select(x => x.Title).ToArray();
}
public override nint NumberOfSections(UITableView tableView)
{
return Groups.Count;
}
public override nint RowsInSection(UITableView tableView, nint section)
{
return Groups[(int)section].People.Count;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell("P") as PasswordCell;
if (cell == null)
{
cell = new PasswordCell("P");
}
var person = GetPerson(indexPath);
cell.Tag = indexPath.Row;
if (person != null)
{
cell.Person = person;
if (person.Image == null)
{
person.Image = PlaceholderImage;
BeginDownloadingImage(person, indexPath);
}
cell.ImageView.Image = person.Image;
}
return cell;
}
#region Image Support
readonly Dictionary<string, UIImage> images = new Dictionary<string, UIImage>();
readonly List<string> imageDownloadsInProgress = new List<string>();
readonly ImageDownloader imageDownloader = new UIKitImageDownloader();
async void BeginDownloadingImage(Password app, NSIndexPath path)
{
// Queue the image to be downloaded. This task will execute
// as soon as the existing ones have finished.
byte[] data = null;
data = await GetImageData(app.GravatarUrl.ToString());
app.Image = UIImage.LoadFromData(NSData.FromArray(data));
InvokeOnMainThread(() =>
{
if (Apps != null)
{
var cell = Controller.TableView.VisibleCells.Where(c => c.Tag == Apps.IndexOf(app)).FirstOrDefault();
if (cell != null)
cell.ImageView.Image = app.Image;
}
});
}
async Task<byte[]> GetImageData(string ImageUrl)
{
byte[] data = null;
try
{
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
using (var c = new GzipWebClient())
data = await c.DownloadDataTaskAsync(ImageUrl);
}
finally
{
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
}
return data;
}
public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
{
return true;
}
public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)
{
if (editingStyle == UITableViewCellEditingStyle.Delete)
{
Groups.RemoveAt(indexPath.Row);
}
}
#endregion
}
當我調試它時,可以看到在BeginDownloadingImage
函數中設置了圖像。 我想念什么? 為什么在單擊單元格之前不更新單元格?
注意:我使用的是Xamarin Employee Directory Sample。
我不確定您可以那樣做。 我將在Person對象上覆蓋您的占位符Image,然后從表視圖調用ReloadRows。
InvokeOnMainThread(() =>
{
if (Apps != null)
{
person.Image = app.Image;
Controller.TableView.ReloadRows (new NSIndexPath[]{ path }, UITableViewRowAnimation.Fade);
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.