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

0

getView() の外部からビューにアクセスすると、期待される動作がほとんど生成されないことに気付きました。リサイクルの仕組みによるものだと思います。2 つの代替オプションが機能します。

1) 実装onClick()するgetView()

2) ロジックをアダプターから除外したい場合は、 でonItemClick()、基になるデータを変更して を呼び出しますadapter.notifyDatasetChanged()。チェックボックスが切り替わります。

于 2012-11-25T20:20:18.203 に答える