我一直有这个问题很长一段时间了。我一点一点地到达那里,但我没有太多时间花在编程上:(
所以我不得不从URL加载图像以便在列表视图中显示,而我几乎就在那里。它们是延迟加载的,我使用的缓存系统运行良好。 问题是,当我开始滚动时,下载的图像位于错误的位置,我无法弄清楚我哪里出错了。
代码的灵感来自以下两个链接:
这个用于布局的想法
http://blog.blundell-apps.com/imageview-with-loading-spinner/
这个用于缓存系统
http://android-developers.blogspot.fr/2010/07/multithreading-for-performance.html
所以这是我的代码:
public class LoaderImageView extends LinearLayout
{
private static final String TAG = "LoderImageView";
private Context mContext;
private ImageView mImage;
private ProgressBar mSpinner;
/* The HashMap that contains the references to the different
* downloads currently running.
*/
public static HashMap<LoaderImageView, BitmapDownloaderTask> tasks =
new LinkedHashMap<LoaderImageView, BitmapDownloaderTask>();
public LoaderImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
mImage = new ImageView(mContext);
mImage.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mSpinner = new ProgressBar(mContext);
mSpinner.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mSpinner.setIndeterminate(true);
addView(mSpinner);
addView(mImage);
Log.w(TAG, "Loading an imageView");
}
public void downloadImage(String url)
{
resetPurgeTimer();
//Log.w(TAG, "Loading: " + url);
if(url.equals(""))
{
mImage.setImageDrawable(mContext.getResources().getDrawable(R.drawable.male));
}
else
{
Bitmap bitmap = getBitmapFromCache(url);
if(bitmap == null)
{
/* The bitmap is not in the cache. */
cancelPotentialDownload(this);
/* Start the new download. */
BitmapDownloaderTask bdt = new BitmapDownloaderTask(this, url);
bdt.execute();
}
else
{
/*The bitmap is in the cache. */
mImage.setImageBitmap(bitmap);
mSpinner.setVisibility(View.GONE);
}
}
}
class BitmapDownloaderTask extends AsyncTask<Void, Void, Bitmap>
{
private String mUrl;
private LoaderImageView mLiv;
public BitmapDownloaderTask(LoaderImageView liv, String url)
{
mLiv = liv;
mUrl = url;
}
@Override
protected void onPreExecute()
{
LoaderImageView.tasks.put(mLiv, this);
mSpinner.setVisibility(View.VISIBLE);
mImage.setVisibility(View.GONE);
Log.w(TAG, "Starting an AsyncTask");
}
@Override
protected Bitmap doInBackground(Void... voids)
{
URL url = null;
try
{
url = new URL(mUrl);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
return BitmapTools.fetchBitmap(url);
}
@Override
protected void onPostExecute(Bitmap bitmap)
{
BitmapDownloaderTask b = tasks.get(mLiv);
if(b == this)
{
LoaderImageView.tasks.remove(this);
mImage.setImageBitmap(bitmap);
}
if (isCancelled())
{
bitmap = null;
}
addBitmapToCache(mUrl, bitmap);
tasks.remove(mLiv);
mSpinner.setVisibility(View.GONE);
mImage.setVisibility(View.VISIBLE);
}
}
/ *更多方法也与缓存有关... * /
这里是 xml 布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/list_item_selector" >
<com.myproject.liste.LoaderImageView
android:id="@+id/visites_image"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />
</RelativeLayout>
我正在使用BaseAdapter和ListActivity创建列表。 此外,我正在按数据页面加载列表:我加载了10个项目,当用户向下滚动时我再加载10个项目,并调用notifyDataSetChange();