2

为什么每次在带有自定义适配器的 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>

列表视图适配器:

    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

对于列表中显示的每一行。

提前致谢!!!!

4

2 回答 2

1

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

ListView.setChoiceMode (ListView.CHOICE_MODE_SINGLE);

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

也许这会对你有所帮助。

于 2016-12-12T21:45:15.320 回答
0

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

1)onClick()实施getView()

2)如果您想将您的逻辑排除在适配器之外,onItemClick()请更改基础数据并调用adapter.notifyDatasetChanged(). 复选框将切换。

于 2012-11-25T20:20:18.203 回答