リモートサーバーから多くの画像をロードする必要がある Android 用の新しいアプリを mono で開発し始めています。これを行うために、レイアウトにプラグインできるビューをプログラムし、バックグラウンドで画像をロードしました。これは、主に使用する予定だったListViewのアダプターで使用するまでは非常にうまく機能します。アプリケーションがいくつかの画像をロードし、他の画像をロードせず、それらを間違った場所にロードします。リストをスクロールするとすぐに画像が正しく読み込まれ始めますが、最初に表示される画像は不完全で間違っています。バックグラウンド プロセス (asynctask、threadpools など) を実行するためにさまざまな戦略を試しましたが、すべて同じ問題を抱えています。コードは次のとおりです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;
using System.Net;
using Android.Graphics;
using ListViewExample;
using System.Threading;
namespace klvpn.components
{
public class WebImageView : RelativeLayout
{
ImageView theImage;
TextView waitingTxt;
Activity context;
Uri imageUri;
WebClient wc;
public WebImageView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
this.context = context as Activity;
this.SetBackgroundColor(Android.Graphics.Color.Black);
this.SetGravity(GravityFlags.Center);
waitingTxt = new TextView(context);
waitingTxt.SetText("...", TextView.BufferType.Normal);
AddView(waitingTxt, new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent));
}
public void SetImageSize(int width, int height)
{
LayoutParameters.Width = width;
LayoutParameters.Height = height;
}
public void SetImageUriStr(string uriStr)
{
imageUri = new Uri(uriStr);
if (theImage == null)
{
theImage = new ImageView(context);
AddView(theImage, 0);
}
wc = new WebClient();
wc.DownloadDataCompleted += new DownloadDataCompletedEventHandler(wc_DownloadDataCompleted);
wc.DownloadDataAsync(imageUri);
}
void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error != null)
{
context.RunOnUiThread(() =>
{
theImage.SetImageResource(Resource.Drawable.noImage_x);
string error = "URI:" + imageUri.OriginalString + "\n" + e.Error.Message;
Log.Error("WebImageView", error);
});
}
else
{
Bitmap bmp = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
context.RunOnUiThread(() =>
{
theImage.SetImageBitmap(bmp);
});
}
wc = null;
}
protected override void OnDetachedFromWindow()
{
base.OnDetachedFromWindow();
if (wc != null)
{
wc.CancelAsync();
}
}
}
}
アダプターの GetView メソッドは次のようになります。
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = this.Episodes[position];
var view = convertView;
if (convertView == null || !(convertView is LinearLayout))
{
view = context.LayoutInflater.Inflate(Resource.Layout.EpisodeItem, parent, false);
}
var imageItem = view.FindViewById<WebImageView>(Resource.Id.imageItem);
var textTop = view.FindViewById<TextView>(Resource.Id.textTop);
var textBottom = view.FindViewById<TextView>(Resource.Id.textBottom);
//imageItem.SetImageResource(item.Image);
imageItem.SetImageSize(100, 36);
imageItem.SetImageUriStr(item.ImageUri);
textTop.SetText(item.Name, TextView.BufferType.Normal);
textBottom.SetText(item.Description, TextView.BufferType.Normal);
return view;
}
この問題を解決する方法はありますか? 私は MonoTouch でこの戦略を使用しましたが、画像のダウンロードがカプセル化されており、ユーザーが何かを見る前にすべてが読み込まれるまで待つ必要がないため、非常に優れています。
ありがとう