android中Listview上的延迟加载图像(初学者级)?

android中Listview上的延迟加载图像(初学者级)?,android,listview,android-lazyadapter,android-lazyloading,Android,Listview,Android Lazyadapter,Android Lazyloading,可能重复: 我正在使用自定义适配器处理listview。我想在上面加载图像和文本视图。图像是从internet URL加载的。我只想显示的图像是可见的列表项的hte用户。我提到了,但是理解代码很复杂。对于初学者,我只想知道如何处理适配器和活动之间的标记。从中,我可以在适配器上设置标记,但不能在listview的空闲状态下显示相应的映像。请帮我说说你的想法。示例代码更容易理解 谢谢 编辑: ApiDemos中的和适配器的组合更有助于理解 对高效适配器所做的更改示例如下: public class

可能重复:

我正在使用自定义适配器处理listview。我想在上面加载图像和文本视图。图像是从internet URL加载的。我只想显示的图像是可见的列表项的hte用户。我提到了,但是理解代码很复杂。对于初学者,我只想知道如何处理适配器和活动之间的标记。从中,我可以在适配器上设置标记,但不能在listview的空闲状态下显示相应的映像。请帮我说说你的想法。示例代码更容易理解

谢谢

编辑:

ApiDemos中的和适配器的组合更有助于理解

对高效适配器所做的更改示例如下:

public class List14 extends ListActivity implements ListView.OnScrollListener {
// private TextView mStatus;

private static boolean mBusy = false;
static ViewHolder holder;

public static class EfficientAdapter extends BaseAdapter {
    private LayoutInflater mInflater;
    private Bitmap mIcon1;
    private Bitmap mIcon2;

    public EfficientAdapter(Context context) {
        // Cache the LayoutInflate to avoid asking for a new one each time.
        mInflater = LayoutInflater.from(context);

        // Icons bound to the rows.
        mIcon1 = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.icon48x48_1);
        mIcon2 = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.icon48x48_2);
    }

    /**
     * The number of items in the list is determined by the number of
     * speeches in our array.
     * 
     * @see android.widget.ListAdapter#getCount()
     */
    public int getCount() {
        return DATA.length;
    }

    /**
     * Since the data comes from an array, just returning the index is
     * sufficent to get at the data. If we were using a more complex data
     * structure, we would return whatever object represents one row in the
     * list.
     * 
     * @see android.widget.ListAdapter#getItem(int)
     */
    public Object getItem(int position) {
        return position;
    }

    /**
     * Use the array index as a unique id.
     * 
     * @see android.widget.ListAdapter#getItemId(int)
     */
    public long getItemId(int position) {
        return position;
    }

    /**
     * Make a view to hold each row.
     * 
     * @see android.widget.ListAdapter#getView(int, android.view.View,
     *      android.view.ViewGroup)
     */
    public View getView(int position, View convertView, ViewGroup parent) {
        // A ViewHolder keeps references to children views to avoid
        // unneccessary calls
        // to findViewById() on each row.

        // 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 = mInflater.inflate(R.layout.list_item_icon_text,
                    null);

            // Creates a ViewHolder and store references to the two children
            // views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.text);
            holder.icon = (ImageView) convertView.findViewById(R.id.icon);

            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }
        if (!mBusy) {
            holder.icon.setImageBitmap(mIcon1);

            // Null tag means the view has the correct data
            holder.icon.setTag(null);
        } else {
            holder.icon.setImageBitmap(mIcon2);

            // Non-null tag means the view still needs to load it's data
            holder.icon.setTag(this);
        }
        holder.text.setText(DATA[position]);

        // Bind the data efficiently with the holder.
        // holder.text.setText(DATA[position]);

        return convertView;
    }

    static class ViewHolder {
        TextView text;
        ImageView icon;
    }
}

private Bitmap mIcon1;
private Bitmap mIcon2;
@Override
public void onCreate(Bundle savedInstanceState) {
    mIcon1 = BitmapFactory.decodeResource(this.getResources(),
            R.drawable.icon48x48_1);
    mIcon2 = BitmapFactory.decodeResource(this.getResources(),
            R.drawable.icon48x48_2);
    super.onCreate(savedInstanceState);
    setListAdapter(new EfficientAdapter(this));
    getListView().setOnScrollListener(this);
}

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    switch (scrollState) {
    case OnScrollListener.SCROLL_STATE_IDLE:
        mBusy = false;

        int first = view.getFirstVisiblePosition();
        int count = view.getChildCount();
        for (int i = 0; i < count; i++) {

            holder.icon = (ImageView) view.getChildAt(i).findViewById(
                    R.id.icon);
            if (holder.icon.getTag() != null) {
                holder.icon.setImageBitmap(mIcon1);
                holder.icon.setTag(null);
            } 
        }

        // mStatus.setText("Idle");
        break;
    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
        mBusy = true;
        // mStatus.setText("Touch scroll");
        break;
    case OnScrollListener.SCROLL_STATE_FLING:
        mBusy = true;
        // mStatus.setText("Fling");
        break;
    }
}
private static final String[] DATA = { "Abbaye de Belloc",
        "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
        "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu"};
}
公共类List14扩展ListActivity实现ListView.OnScrollListener{
//私有文本视图mStatus;
私有静态布尔值mBusy=false;
静态取景器;
公共静态类EfficientAdapter扩展BaseAdapter{
私人停车场;
私有位图mIcon1;
私有位图mIcon2;
公共效率适配器(上下文){
//缓存LayoutFlate以避免每次请求新的LayoutFlate。
mInflater=LayoutInflater.from(上下文);
//绑定到行的图标。
mIcon1=BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon48x48_1);
mIcon2=BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon48x48_2);
}
/**
*列表中项目的数量由项目的数量决定
*我们的演讲阵容。
* 
*@see android.widget.ListAdapter#getCount()
*/
public int getCount(){
返回数据长度;
}
/**
*由于数据来自一个数组,因此只返回索引是非常困难的
*足够获取数据。如果我们使用更复杂的数据
*结构中,我们将返回表示
*名单。
* 
*@see android.widget.ListAdapter#getItem(int)
*/
公共对象getItem(int位置){
返回位置;
}
/**
*将数组索引用作唯一id。
* 
*@see android.widget.ListAdapter#getItemId(int)
*/
公共长getItemId(int位置){
返回位置;
}
/**
*创建一个视图以容纳每一行。
* 
*@see android.widget.ListAdapter#getView(int,android.view.view,
*android.view.ViewGroup)
*/
公共视图getView(int位置、视图转换视图、视图组父视图){
//ViewHolder保留对子视图的引用以避免
//不必要的电话
//在每行上查找dviewbyd()。
//当convertView不为null时,我们可以直接重用它,因为
//没必要
//我们只在转换视图时对新视图进行充气
//供应
//按ListView设置为空。
if(convertView==null){
convertView=mInflater.充气(R.layout.list\u item\u icon\u text,
无效);
//创建ViewHolder并存储对这两个子对象的引用
//观点
//我们希望将数据绑定到。
holder=新的ViewHolder();
holder.text=(TextView)convertView.findViewById(R.id.text);
holder.icon=(ImageView)convertView.findViewById(R.id.icon);
convertView.setTag(支架);
}否则{
//取回ViewHolder以快速访问TextView
//还有ImageView。
holder=(ViewHolder)convertView.getTag();
}
如果(!mBusy){
holder.icon.setImageBitmap(mIcon1);
//Null标记表示视图具有正确的数据
holder.icon.setTag(空);
}否则{
holder.icon.setImageBitmap(mIcon2);
//非空标记表示视图仍需要加载其数据
holder.icon.setTag(本);
}
holder.text.setText(数据[位置]);
//与持有者有效地绑定数据。
//holder.text.setText(数据[位置]);
返回视图;
}
静态类视窗夹{
文本查看文本;
图像视图图标;
}
}
私有位图mIcon1;
私有位图mIcon2;
@凌驾
创建时的公共void(Bundle savedInstanceState){
mIcon1=BitmapFactory.decodeResource(this.getResources(),
R.drawable.icon48x48_1);
mIcon2=BitmapFactory.decodeResource(this.getResources(),
R.drawable.icon48x48_2);
super.onCreate(savedInstanceState);
setListAdapter(新的EfficientAdapter(本));
getListView().setOnScrollListener(此);
}
public void onScroll(AbsListView视图,int firstVisibleItem,
int visibleItemCount,int totalItemCount){
}
公共无效onScrollStateChanged(AbsListView视图,int scrollState){
开关(滚动状态){
案例OnScrollListener.SCROLL\u STATE\u IDLE:
mBusy=假;
int first=view.getFirstVisiblePosition();
int count=view.getChildCount();
for(int i=0;ipublic class MediaItemAdapter extends ArrayAdapter<MediaItem> {
  private final static String TAG = "MediaItemAdapter";
  private int resourceId = 0;
  private LayoutInflater inflater;
  private Context context;

  private ImageThreadLoader imageLoader = new ImageThreadLoader();

  public MediaItemAdapter(Context context, int resourceId, List<MediaItem> mediaItems) {
    super(context, 0, mediaItems);
    this.resourceId = resourceId;
    inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.context = context;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {

    View view;
    TextView textTitle;
    TextView textTimer;
    final ImageView image;

    view = inflater.inflate(resourceId, parent, false);

    try {
      textTitle = (TextView)view.findViewById(R.id.text);
      image = (ImageView)view.findViewById(R.id.icon);
    } catch( ClassCastException e ) {
      Log.e(TAG, "Your layout must provide an image and a text view with ID's icon and text.", e);
      throw e;
    }

    MediaItem item = getItem(position);
    Bitmap cachedImage = null;
    try {
      cachedImage = imageLoader.loadImage(item.thumbnail, new ImageLoadedListener() {
      public void imageLoaded(Bitmap imageBitmap) {
      image.setImageBitmap(imageBitmap);
      notifyDataSetChanged();                }
      });
    } catch (MalformedURLException e) {
      Log.e(TAG, "Bad remote image URL: " + item.thumbnail, e);
    }

    textTitle.setText(item.name);

    if( cachedImage != null ) {
      image.setImageBitmap(cachedImage);
    }

    return view;
  }
}
EfficientAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    mIcon1 = BitmapFactory.decodeResource(this.getResources(),
            R.drawable.icon48x48_1);
    mIcon2 = BitmapFactory.decodeResource(this.getResources(),
            R.drawable.icon48x48_2);
    super.onCreate(savedInstanceState);
    adapter=new EfficientAdapter(this);
    setListAdapter(adapter);
    getListView().setOnScrollListener(this);
}

public void onScroll(AbsListView view, int firstVisibleItem,
    int visibleItemCount, int totalItemCount) {
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    switch (scrollState) {
    case OnScrollListener.SCROLL_STATE_IDLE:
        mBusy = false;
        adapter.notifyDataSetChanged() 
        break;
    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
        mBusy = true;
        // mStatus.setText("Touch scroll");
        break;
    case OnScrollListener.SCROLL_STATE_FLING:
        mBusy = true;
        // mStatus.setText("Fling");
        break;
    }
}
public class List14 extends ListActivity implements ListView.OnScrollListener {
// private TextView mStatus;

private static boolean mBusy = false;
static ViewHolder holder;

public static class EfficientAdapter extends BaseAdapter {
    private LayoutInflater mInflater;
    private Bitmap mIcon1;
    private Bitmap mIcon2;
    private Context mContext;

    public EfficientAdapter(Context context) {
        // Cache the LayoutInflate to avoid asking for a new one each time.
        mInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContext = context;
        // Icons bound to the rows.
        mIcon1 = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.icon48x48_1);
        mIcon2 = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.icon48x48_2);
    }

    /**
     * The number of items in the list is determined by the number of
     * speeches in our array.
     * 
     * @see android.widget.ListAdapter#getCount()
     */
    public int getCount() {
        return DATA.length;
    }

    /**
     * Since the data comes from an array, just returning the index is
     * sufficent to get at the data. If we were using a more complex data
     * structure, we would return whatever object represents one row in the
     * list.
     * 
     * @see android.widget.ListAdapter#getItem(int)
     */
    public Object getItem(int position) {
        return position;
    }

    /**
     * Use the array index as a unique id.
     * 
     * @see android.widget.ListAdapter#getItemId(int)
     */
    public long getItemId(int position) {
        return position;
    }

    /**
     * Make a view to hold each row.
     * 
     * @see android.widget.ListAdapter#getView(int, android.view.View,
     *      android.view.ViewGroup)
     */
    public View getView(int position, View convertView, ViewGroup parent) {
        // A ViewHolder keeps references to children views to avoid
        // unneccessary calls
        // to findViewById() on each row.

        // 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 = mInflater.inflate(R.layout.list_item_icon_text,
                    parent, false);

            // Creates a ViewHolder and store references to the two children
            // views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.text);
            holder.icon = (ImageView) convertView.findViewById(R.id.icon);

             convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
             holder = (ViewHolder) convertView.getTag();
        }

        if (!mBusy) {

            holder.icon.setImageBitmap(mIcon1);

            // Null tag means the view has the correct data
            holder.icon.setTag(null);

        } else {
            holder.icon.setImageBitmap(mIcon2);

            // Non-null tag means the view still needs to load it's data
            holder.icon.setTag(this);
        }
        holder.text.setText(DATA[position]);

        // Bind the data efficiently with the holder.
        // holder.text.setText(DATA[position]);

        return convertView;
    }

    static class ViewHolder {
        TextView text;
        ImageView icon;
    }
}

private Bitmap mIcon1;
private Bitmap mIcon2;

@Override
public void onCreate(Bundle savedInstanceState) {
    mIcon1 = BitmapFactory.decodeResource(this.getResources(),
            R.drawable.icon48x48_1);
    mIcon2 = BitmapFactory.decodeResource(this.getResources(),
            R.drawable.icon48x48_2);
    super.onCreate(savedInstanceState);
    setListAdapter(new EfficientAdapter(this));
    getListView().setOnScrollListener(this);
}

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    switch (scrollState) {
    case OnScrollListener.SCROLL_STATE_IDLE:
        mBusy = false;

        int first = view.getFirstVisiblePosition();
        int count = view.getChildCount();

        for (int i = 0; i < count; i++) {

            holder.icon = (ImageView) view.getChildAt(i).findViewById(
                    R.id.icon);
            if (holder.icon.getTag() != null) {
                holder.icon.setImageBitmap(IMAGE[first+i]);// this is the image url array.
                holder.icon.setTag(null);
            }
        }

        // mStatus.setText("Idle");
        break;
    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
        mBusy = true;
        // mStatus.setText("Touch scroll");
        break;
    case OnScrollListener.SCROLL_STATE_FLING:
        mBusy = true;
        // mStatus.setText("Fling");
        break;
    }
}

private static final String[] DATA = { "Abbaye de Belloc",
        "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
        "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu",
        "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
        "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano" };
  }