如何實現ListView+image+text

最近學習ListView的用法,需要實現一個帶圖片和文字的ListView,然後在點擊或者選擇到每個Item的時候改變這個Item的圖片。
帶圖片和文字的ListView已經實現出來,但是在實現改變圖片的時候卻不知道怎么實現了,望指教:

package lee.mylistview2;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;

public class MyListView2 extends Activity {

mySimpleAdapter mAdapter;
private ListView listView;
private ArrayList<HashMap<String, Object>> users = new ArrayList<HashMap<String, Object>>();

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    for (int i = 0; i < 10; i++) {
        HashMap<String, Object> user = new HashMap<String, Object>();
        user.put("img", R.drawable.user);
        user.put("username", "姓名(" + i + ")");
        user.put("age", (20 + i) + "");
        users.add(user);
    }

    mAdapter = new mySimpleAdapter(this);
    listView = ((ListView) findViewById(R.id.list));
    listView.setAdapter(mAdapter);
    //listView.setSelection(selectPosition);

    listView.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
            listView.setAdapter(mAdapter);
        }
    });


    listView.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                int position, long arg3) {
            mAdapter.setVisible();
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {

        }
    });

}
class mySimpleAdapter extends BaseAdapter{

    private LayoutInflater mInflater;
    private Bitmap mIcon1, mIcon2;

    public mySimpleAdapter(Context c){
        mInflater = LayoutInflater.from(c);

        // Icons bound to the rows.
        mIcon1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.user);
        mIcon2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.black);
    }


    public int getCount(){
        return users.size();
    }
    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }


    ViewHolder holder;

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


        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.user, null);

            // Creates a ViewHolder and store references to the two children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.text1 = (TextView) convertView.findViewById(R.id.name);
            holder.text2 = (TextView) convertView.findViewById(R.id.age);
            holder.icon = (ImageView) convertView.findViewById(R.id.img);
            //holder.icon.setVisibility(View.INVISIBLE);
            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }

            // Bind the data efficiently with the holder.
            holder.text1.setText(users.get(position).get("username").toString());
            holder.text2.setText(users.get(position).get("age").toString());
            holder.icon.setImageBitmap(mIcon2);

        //holder.icon.setVisibility(View.INVISIBLE);

        return convertView;
    }

    public void setVisible(){
        holder.icon.setImageBitmap(mIcon1);
        holder.icon.setVisibility(View.VISIBLE);
        //notifyDataSetInvalidated();
        notifyDataSetChanged();
    }
}
static class ViewHolder {
    TextView text1, text2;
    ImageView icon;
}

}


現在的效果為:
问题补充
我也試用SimpleAdapter來實現,也是可以做出帶圖片的ListView的界面,但是就是不能實現點擊每個Item時候,改變前面的圖片的功能。。。。
问题补充
給自己頂頂

结果正确了.选中时图标变化[code="java"]
package com.me.list;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import com.me.R;

/**
*

  • @author archko
    */
    public class MyListView2 extends Activity{

    MySimpleAdapter mAdapter;
    private ListView listView;
    private ArrayList> users=new ArrayList>();
    private static final String TAG="MyListView2";
    private int pos=-1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list1);

    for(int i=0 ; i<3 ; i++){
        HashMap<String,Object> user=new HashMap<String,Object>();
        user.put("img",R.drawable.checkon);
        user.put("username","姓名("+i+")");
        user.put("age",(20+i)+"");
        users.add(user);
    }
    
    mAdapter=new MySimpleAdapter(this);
    listView=((ListView)findViewById(R.id.ListView01));
    listView.setAdapter(mAdapter);
    //listView.setSelection(selectPosition);   
    
    listView.setOnItemClickListener(new OnItemClickListener(){
    
        @Override
        public void onItemClick(AdapterView<?> arg0,View arg1,int position,long arg3){
            //listView.setAdapter(mAdapter);
            mAdapter.setVisible();
            pos=position;
        }
    });
    
    listView.setOnItemSelectedListener(new OnItemSelectedListener(){
    
        @Override
        public void onItemSelected(AdapterView<?> arg0,View arg1,int position,long arg3){
            mAdapter.setVisible();
            pos=position;
        }
    
        @Override
        public void onNothingSelected(AdapterView<?> arg0){
        }
    });
    

    }

    class MySimpleAdapter extends BaseAdapter{

    private LayoutInflater mInflater;
    private Bitmap mIcon1, mIcon2;
    private int count=0;
    
    public MySimpleAdapter(Context c){
        mInflater=LayoutInflater.from(c);
    
        // Icons bound to the rows.   
        mIcon1=BitmapFactory.decodeResource(c.getResources(),R.drawable.checkon);
        mIcon2=BitmapFactory.decodeResource(c.getResources(),R.drawable.checkoff);
    }
    
    public int getCount(){
        return users.size();
    }
    
    public Object getItem(int position){
        return position;
    }
    
    public long getItemId(int position){
        return position;
    }
    ViewHolder holder;
    
    //这个方法在Activity载入时会调用两次?,而且是列表有几个项就循环几次.
    //而convertView只有在Activity初始化时才会是空.
    @Override
    public View getView(int position,View convertView,ViewGroup parent){
    
        if(convertView==null){
            convertView=mInflater.inflate(R.layout.list_items,null);
    
            // Creates a ViewHolder and store references to the two children views   
            // we want to bind data to.   
            holder=new ViewHolder();
            holder.itemTitle=(TextView)convertView.findViewById(R.id.ItemTitle);
            holder.itemText=(TextView)convertView.findViewById(R.id.ItemText);
            holder.itemIcon=(ImageView)convertView.findViewById(R.id.ItemImage);
            holder.itemIcon.setImageBitmap(mIcon1);
            convertView.setTag(holder);
            Log.d(TAG,"getView.if end,position:"+position+" text:"+holder.itemText.getText());
        }else{
            // Get the ViewHolder back to get fast access to the TextView and the ImageView.   
            holder=(ViewHolder)convertView.getTag();
            Log.d(TAG,"getView.else end,position:"+position+" text:"+holder.itemText.getText());
        }
    
        // Bind the data efficiently with the holder.
        holder.itemTitle.setText(users.get(position).get("username").toString());
        holder.itemText.setText(users.get(position).get("age").toString());
        holder.itemIcon.setImageBitmap((position==pos)?mIcon1:mIcon2);
        count++;
        Log.d(TAG,"getView.holder set end.count:"+count);
        return convertView;
    }
    
    public void setVisible(){
        //holder.itemIcon.setImageBitmap(mIcon2);
        //holder.itemIcon.setVisibility(View.VISIBLE);
        //notifyDataSetInvalidated();
        //Notifies the attached View that the underlying data has been changed and it should refresh itself.
        notifyDataSetChanged();
        Log.d(TAG,"setVisible");
    }
    

    }

    static class ViewHolder{

    TextView itemTitle, itemText;
    ImageView itemIcon;
    

    }
    }

[/code]
运行的LOGCAT:从开始进入这个Activity开始:
D/MyListView2( 452): setVisible
D/MyListView2( 452): getView.else end,position:0 text:22
D/MyListView2( 452): getView.holder set end.count:10
D/MyListView2( 452): getView.else end,position:1 text:21
D/MyListView2( 452): getView.holder set end.count:11
D/MyListView2( 452): getView.else end,position:2 text:20
D/MyListView2( 452): getView.holder set end.count:12
D/MyListView2( 452): getView.else end,position:0 text:22
D/MyListView2( 452): getView.holder set end.count:13
D/MyListView2( 452): getView.else end,position:1 text:20
D/MyListView2( 452): getView.holder set end.count:14
D/MyListView2( 452): getView.else end,position:2 text:21
D/MyListView2( 452): getView.holder set end.count:15
D/MyListView2( 452): setVisible
D/MyListView2( 452): getView.else end,position:0 text:22
D/MyListView2( 452): getView.holder set end.count:16
D/MyListView2( 452): getView.else end,position:1 text:20
D/MyListView2( 452): getView.holder set end.count:17
D/MyListView2( 452): getView.else end,position:2 text:21
D/MyListView2( 452): getView.holder set end.count:18
D/MyListView2( 452): getView.else end,position:1 text:22
D/MyListView2( 452): getView.holder set end.count:19
D/MyListView2( 452): getView.else end,position:0 text:21
D/MyListView2( 452): getView.holder set end.count:20
D/MyListView2( 452): getView.else end,position:2 text:20
D/MyListView2( 452): getView.holder set end.count:21
D/MyListView2( 452): setVisible
D/MyListView2( 452): getView.else end,position:0 text:22
D/MyListView2( 452): getView.holder set end.count:22
D/MyListView2( 452): getView.else end,position:1 text:20
D/MyListView2( 452): getView.holder set end.count:23
D/MyListView2( 452): getView.else end,position:2 text:21
D/MyListView2( 452): getView.holder set end.count:24
D/MyListView2( 452): getView.else end,position:2 text:22
D/MyListView2( 452): getView.holder set end.count:25
D/MyListView2( 452): getView.else end,position:1 text:21
D/MyListView2( 452): getView.holder set end.count:26
D/MyListView2( 452): getView.else end,position:0 text:20
D/MyListView2( 452): getView.holder set end.count:27

运行之后这个LOGCAT你看过没有?先是setOnItemSelectedListener
点击项时执行,或是你用键盘选中时执行setOnItemClickListener
然后才是GetView里的代码执行,可想而知.你选中,然后它设置了图标setVisible(),结果在GetView里又执行了
holder.text1.setText(users.get(position).get("username").toString());

holder.text2.setText(users.get(position).get("age").toString());

holder.icon.setImageBitmap(mIcon2);
这个会执行很多次.太多了我改为3行,结果显示执行6次,我标注了LOG分别是IF,ELSE和它后面的,还有SetVisible.
D/MyListView2( 279): setVisible
D/MyListView2( 279): getView.else end,position:0
D/MyListView2( 279): getView.holder set end
D/MyListView2( 279): getView.else end,position:1
D/MyListView2( 279): getView.holder set end
D/MyListView2( 279): getView.else end,position:2
D/MyListView2( 279): getView.holder set end
D/MyListView2( 279): getView.else end,position:0
D/MyListView2( 279): getView.holder set end
D/MyListView2( 279): getView.else end,position:1
D/MyListView2( 279): getView.holder set end
D/MyListView2( 279): getView.else end,position:2
D/MyListView2( 279): getView.holder set end
所以永远是不会改变的.