Databinding a ListView with Mono for Android: Listing 5
The GetView method.
public class CustomListAdapter : BaseAdapter
{
Activity context;
Dictionary<String,Bitmap> urlToImageMap = new Dictionary<String,Bitmap>();
public List<Tweet> items;
public CustomListAdapter(Activity context, List<Tweet> listItems) //We need a context to inflate our row view from
: base()
{
this.context = context;
this.items = listItems;
}
public override int Count
{
get { return items.Count; }
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
//Get our object for this position
var item = items[position];
//Try to reuse convertView if it's not null, otherwise inflate it from our item layout
// This gives us some performance gains by not always inflating a new view
// This will sound familiar to MonoTouch developers with UITableViewCell.DequeueReusableCell()
var view = (convertView ??
context.LayoutInflater.Inflate(
Resource.Layout.tweet,
parent,
false)) as LinearLayout;
//imageItem.Click += new EventHandler(imageItem_Click);
try
{
//Find references to each subview in the list item's view
var imageItem = view.FindViewById(Resource.Id.imageItem) as ImageView;
var textTop = view.FindViewById(Resource.Id.textTop) as TextView;
var textBottom = view.FindViewById(Resource.Id.textBottom) as TextView;
//Assign this item's values to the various subviews
if (!String.IsNullOrEmpty(item.ProfileImage))
{
string documents = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string fileName = System.Guid.NewGuid().ToString();
string file = System.IO.Path.Combine(documents, fileName);
var ptt = new PassToThread() { FileName = file, imageV = imageItem, UrlToDownload = item.ProfileImage };
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(downloadImage), ptt);
}
Android.Util.Log.Info("custom adapter", item.ProfileImage);
textTop.Text = item.Status;
textBottom.Text = item.StatusDate;
}
catch (System.Exception sysExc)
{
Android.Util.Log.Error("custom adapter", sysExc.Message);
}
//Finally return the view
return view;
}
private void downloadImage(Object o)
{
try
{
var ptt = (PassToThread)o;
Bitmap bitmap;
lock (this) {
if (urlToImageMap.ContainsKey(ptt.UrlToDownload))
{
bitmap = urlToImageMap[ptt.UrlToDownload];
}
else
{
var imageUrl = new Java.Net.URL(ptt.UrlToDownload);
bitmap = Android.Graphics.BitmapFactory.DecodeStream (imageUrl.OpenStream ());
urlToImageMap.Add(ptt.UrlToDownload,bitmap);
File.Delete(ptt.FileName);
}
}
context.RunOnUiThread(() => ptt.imageV.SetImageBitmap(bitmap));
}
catch (System.Net.WebException wec)
{
Android.Util.Log.Error("twitter timelines", wec.Message);
}
}
public Tweet GetItemAtPosition(int position)
{
return items[position];
}
private class PassToThread
{
public string UrlToDownload { get; set; }
public string FileName { get; set; }
public ImageView imageV { get; set; }
}
}
About the Author
Wallace (Wally) B. McClure has authored books on iPhone programming with Mono/Monotouch, Android programming with Mono for Android, application architecture, ADO.NET, SQL Server and AJAX. He's a Microsoft MVP, an ASPInsider and a partner at Scalable Development Inc. He maintains a blog, and can be followed on Twitter.