我使用此示例中的ListAdapter:
示例不是很好,因为根据滚动速度,列表中的元素会被绘制几次。那是因为只重用了一个
private FakeImageLoader mFakeImageLoader;
如果FakeImageLoader.java getImage()会加载一个真实的图像。 要使这个示例运行并保持高效,需要做些什么?
public class OptimizedListAdapter extends BaseAdapter{
...
private FakeImageLoader mFakeImageLoader;
public OptimizedListAdapter(Context cxt)
{
// Cache the LayoutInflate to avoid asking for a new one each time.
mLayoutInflater = LayoutInflater.from(cxt);
mFakeImageLoader = new FakeImageLoader(cxt);
...
public View getView(final int position, View convertView, ViewGroup parent)
{
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if(convertView==null)
{
convertView = mLayoutInflater.inflate(R.layout.listitem, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
convertView.setTag(holder);
}else
{
holder = (ViewHolder) convertView.getTag();
}
//holder.icon.setImageDrawable(drawable);
holder.text.setText(new StringBuffer(ITEM_PRE_TEXT).append(position));
holder.timestamp.setText(""+(System.currentTimeMillis()-START_TIMESTAMP));
holder.position = position;
//during a fast scroll this could start 100's of threads, need a thread pool processing them!
//see previous ImageLoader.
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return mFakeImageLoader.getImage();
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if(v.position == position)
{
v.icon.setImageBitmap(result);
}
}
}.execute(holder);
//holder.icon.setImageBitmap(mFakeImageLoader.getImage());
return convertView;
}
感谢塔塔
答案 0 :(得分:1)
我在一个应用程序中使用了这个universal image loader library通用图像加载器库来下载图像,这对我来说更有用。
答案 1 :(得分:0)
这是我用于延迟加载的内容。请注意,此代码已被修改(删除了您不需要查看xD的内容)并且未经过测试,只是为了分享这个想法。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public final class ResultsAdapter
extends BaseAdapter
{
// this is used for runnint on UI thread, as View.post did not always executed for me
private Activity host;
private ExecutorService service;
public ResultsAdapter(Activity host)
{
this.host = host;
}
/**
* Set new data to this adapter. Or if your data will not change, you can do this in constructor
*/
public void refresh(List<MyClass> data)
{
if (this.service != null) {
this.service.shutdownNow();
}
this.data = data;
this.service = Executors.newSingleThreadExecutor();
this.notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
...
MyClass item = items.get(position);
holder.image.setTag(Long.valueOf(item.getId()));
try {
this.service.submit(new Job(current.getImageURL(), h.logo, Long.valueOf(item.getId())));
} catch (Throwable e) {
}
...
}
private final class Job
implements Runnable
{
private final ImageView logo;
private final Long logoTag;
private final String URL;
private Job(String url; ImageView logo, Long logoTag)
{
this.URL = url;
this.logo = logo;
this.logoTag = logoTag;
}
@Override
public void run()
{
Thread t = Thread.currentThread();
t.setPriority(Thread.NORM_PRIORITY - 1); //not to load ui thread much
...
//load my stuff
...
// logo tag could change during scrolling. getView could be called for the same reused view, so we check if we are not currently setting old data.
if (logo.getTag().equals(logoTag)) {
host.runOnUiThread(new Runnable()
{
@Override
public void run()
{
logo.setImageBitmap(myStuff);
}
}
});
}
}
}
但是在快速滚动过程中我仍然会遇到一些数据变化。告诉我,如果这使你不那么明显。