为什么在调用onItemClick()时,为ListVIew中显示的每一行再次调用getView()?

时间:2012-05-24 21:50:00

标签: java android

为什么每次使用自定义适配器在ListView上调用onItemClick()事件时,都会再次调用适配器中的getView()方法?

我在API级别7中有以下代码,当我尝试更改行的CheckedTextView对象中的选中值(存储在ViewHolder中)时,调用每行的适配器getView()并且得到了一个奇怪的行为(listView中的选定行检查/取消选中另一行中的CheckedTextView):

活动的代码是:

public class EnvioImagenesActivity extends Activity implements OnItemClickListener {

    ListView listView;
    private EnvioImagenAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.envio_imagenes);
        listView=(ListView) findViewById(R.id.listViewEnvios);
        adapter=new EnvioImagenAdapter(this,Store.getImages());
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);
    }

    public void onItemClick(AdapterView<?> arg0, View view, int pos,
            long id) {
        ViewHolder holder=(ViewHolder) view.getTag();
        holder.checkedTextView.toggle();
    }


}

Xml布局活动的代码是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/envioImagenes"
        android:textAppearance="?android:attr/textAppearanceLarge" android:gravity="center"/>


    <ListView
        android:id="@+id/listViewEnvios"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
      android:choiceMode="multipleChoice">

    </ListView>


</LinearLayout>

listview适配器:

    public class EnvioImagenAdapter extends BaseAdapter {

        private List<ImageUri> items;
        private Context context;

        public EnvioImagenAdapter(Context context, List<ImageUri> items) {
            this.context=context;
            this.items = items;
        }

        public int getCount() {
            return items.size();
        }

        public Object getItem(int position) {
            return items.get(position);
        }

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

        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("---getView() method called");
            View v = convertView;
            ViewHolder holder;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.row_envio_imagen, null);
                holder = new ViewHolder();
                holder.imageView = (ImageView) v.findViewById(R.id.imageView1);
                holder.textView = (TextView) v.findViewById(R.id.textView1);
                holder.temporalProgressBar = (ProgressBar) v
                        .findViewById(R.id.progressBar1);
                holder.checkedTextView = (CheckedTextView) v
                        .findViewById(R.id.checkedTextView12);
                holder.selected = true;
                holder.position = position;
                v.setTag(holder);
            } else {
                holder = (ViewHolder) v.getTag();
            }
            ImageUri imageUri = items.get(position);
            File f = new File(imageUri.getImageUri().getPath());
            String fileSize = Util.formatFileSize(f.length());
            holder.textView.setText(fileSize);
            new ImageTask(imageUri).execute(holder);
            return v;
        }

        class ImageTask extends AsyncTask<ViewHolder, Void, Bitmap> {

            public ImageTask(ImageUri imageUri) {
                this.imageUri = imageUri;
            }

            private ImageUri imageUri;
            private ViewHolder viewHolder;

            @Override
            protected Bitmap doInBackground(ViewHolder... params) {
                viewHolder = params[0];
                Bitmap bmp = BitmapFactory.decodeFile(imageUri.getThumbUri()
                        .getPath());
                return bmp;
            }

            protected void onPostExecute(Bitmap result) {
                super.onPostExecute(result);
                viewHolder.temporalProgressBar.setVisibility(View.GONE);
                viewHolder.imageView.setVisibility(View.VISIBLE);
                viewHolder.imageView.setImageBitmap(result);
            };

        }

        class ViewHolder {
            public int position;
            CheckedTextView checkedTextView;
            ProgressBar temporalProgressBar;
            ImageView imageView;
            TextView textView;
            boolean selected;
        }

    }

每行的xml布局是:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip" >

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="45dip"
        android:layout_height="45dip"
        android:layout_alignParentLeft="true" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="45dip"
        android:layout_height="45dip"
        android:layout_alignParentLeft="true" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dip"
        android:layout_toRightOf="@id/imageView1" />

    <CheckedTextView
        android:id="@+id/checkedTextView12"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checkMark="?android:attr/textCheckMark"
        android:checked="true" 
        android:layout_alignParentRight="true">
    </CheckedTextView>


    <ProgressBar
        android:id="@+id/progressBar2"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_height="wrap_content"
        android:layout_width="0dip"
        android:layout_below="@+id/textView1"
        android:layout_toLeftOf="@id/checkedTextView12"
        android:layout_toRightOf="@id/imageView1"
        android:paddingLeft="5dip"
        android:paddingTop="2dip" />


</RelativeLayout>

当我在模拟器中运行应用程序并连续点击时,我在LogCat中获取:

System.out(2947): ---getView() method called

列表中显示的每一行。

提前致谢!!!!

2 个答案:

答案 0 :(得分:1)

我在代码中遇到了类似的问题

ListView.setChoiceMode (ListView.CHOICE_MODE_SINGLE);

当您点击每个项目的项目时,再次召唤getview,在您的情况下,您可以尝试删除android:choiceMode="multipleChoice"

也许这会对你有帮助。

答案 1 :(得分:0)

我注意到从getView()外部访问视图很少产生预期的行为。我想这是因为回收机制。两种替代选择有效:

1)在onClick()

中实施getView()

2)如果您希望将逻辑从适配器中移出,请在onItemClick()中更改基础数据并调用adapter.notifyDatasetChanged()。该复选框将切换。