Просмотр списка Android с помощью ViewHolder

У меня проблема. Я пытаюсь изменить значок в своем списке, после того как он был нажат. Он работает правильно, хотя не изменяется только щелкнутые значки, но также и те, кто не отображается. Например, если щелкнуть значок в первом элементе списка, также изменится пятый значок. Это поведение повторяется для всех следующих элементов (каждые пять элементов списка). Это мой метод getView:

public class AlphabeticalAdapter extends ArrayAdapter { int layoutResourceId; private final Context context; private List data; private ProgressDialog mProgressDialog; private ImageView downloadImageButton; public AlphabeticalAdapter(Context context, int resource, List data){ super(context, resource, data); this.layoutResourceId = resource; this.context = context; this.data = data; } public View getView(int position, View convertView, ViewGroup parent) { // View rowView = convertView; final ViewHolder viewHolder; if (convertView == null) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.catalogslist_single_row, parent, false); viewHolder = new ViewHolder(); viewHolder.catlogTitle=(TextView)convertView.findViewById(R.id.txtTitle); viewHolder.icon=(ImageView)convertView.findViewById(R.id.imageView2); viewHolder.downloadImageButton=(ImageView)convertView.findViewById(R.id.downloadImageButton); //downloadImageButton = (ImageView)rowView.findViewById(R.id.downloadImageButton); viewHolder.position = position; viewHolder.downloadImageButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out.println("DOWNLOAD PRESSED"); viewHolder.downloadImageButton = (ImageView)v.findViewById(R.id.downloadImageButton); viewHolder.downloadImageButton.setImageResource(R.drawable.icon_ok); viewHolder.downloadImageButton.setTag("downloaded"); //rowView.setTag("downloaded"); } }); convertView.setTag(viewHolder); } else{ viewHolder= (ViewHolder)convertView.getTag(); } viewHolder.catlogTitle.setText(data.get(position)); viewHolder.catlogTitle.setTypeface(regularDin); viewHolder.icon.setImageResource(R.drawable.cata); if(viewHolder.downloadImageButton.getTag() == "downloaded"){ downloadImageButton = (ImageView)convertView.findViewById(R.id.downloadImageButton); downloadImageButton.setImageResource(R.drawable.icon_ok); } else{ downloadImageButton = (ImageView)convertView.findViewById(R.id.downloadImageButton); downloadImageButton.setImageResource(R.drawable.icon_download); } viewHolder.position = position; return convertView; } //close getView 

И это мой class ViewHolder:

  static class ViewHolder{ ImageView downloadImageButton; TextView catlogTitle; ImageView icon; int position; } 

4 Solutions collect form web for “Просмотр списка Android с помощью ViewHolder”

Измените свой код ниже. Думаю, тебе это не хватает.

 public class AlphabeticalAdapter extends ArrayAdapter { int layoutResourceId; private final Context context; private List data; private List tags; private ProgressDialog mProgressDialog; private ImageView downloadImageButton; public AlphabeticalAdapter(Context context, int resource, List data) { super(context, resource, data); this.layoutResourceId = resource; this.context = context; this.data = data; tags = new ArrayList(); int size = data.size(); for (int i = 0; i < size; i++) { tags.add("tag"); } } static class ViewHolder { ImageView downloadImageButton; TextView catlogTitle; ImageView icon; int position; } public View getView(final int position, View convertView, ViewGroup parent) { // View rowView = convertView; final ViewHolder viewHolder; if (convertView == null) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // convertView = inflater.inflate(R.layout.catalogslist_single_row, // parent, false); viewHolder = new ViewHolder(); viewHolder.position = position; viewHolder.downloadImageButton .setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out.println("DOWNLOAD PRESSED"); viewHolder.downloadImageButton.setTag("downloaded"); tags.add(position, "downloaded"); } }); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.catlogTitle.setText(data.get(position)); viewHolder.catlogTitle.setTypeface(regularDin); viewHolder.icon.setImageResource(R.drawable.cata); if (tags.get(position) == "downloaded") { downloadImageButton.setImageResource(R.drawable.icon_ok); } else { downloadImageButton.setImageResource(R.drawable.icon_download); } viewHolder.position = position; return convertView; } // close getView } 

В convertViews столько же, сколько видимых строк в одном и том же времени (система повторно использует его). Таким образом, у вас на самом деле есть 5 convertView , и из-за этого у вас есть 5 ImageView для значков. Проблема в том, что вы используете тег ImageView для хранения «загруженной» информации. Это 5 состояний, и именно поэтому вы видите каждую пятую строку, загружаемую во время прокрутки в списке.

Думаю, теперь вы видите, что это не сработает. Вам нужно сохранить загруженное состояние для каждого элемента, поэтому вам нужно изменить базовый List to List , где ListItem может сохранять загруженное состояние для фактической строки.

После этого все, что вам нужно сделать, – это обновить ImageView от convertViewgetView() ), чтобы показать правильный значок.

Измените свой код следующим образом. Добавьте null check с помощью convertView перед блоком try.

  final MenuItem menuItem = getItem(position); View view = convertView; final ViewHolder viewHolder; if (convertView == null) { LayoutInflater inflater; inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.menu_item, parent, false); viewHolder = new ViewHolder(); // viewHolder.half = (TextView) view.findViewById(R.id.half); viewHolder.name = (TextView) view.findViewById(R.id.name); viewHolder.description = (TextView) view.findViewById(R.id.description); viewHolder.price = (TextView) view.findViewById(R.id.price); viewHolder.add = (Button) view.findViewById(R.id.add); viewHolder.selectedView = view.findViewById(R.id.selectedView); viewHolder.remove = (Button) view.findViewById(R.id.remove); viewHolder.total = (TextView) view.findViewById(R.id.itemTotal); viewHolder.quantity = (TextView) view.findViewById(R.id.quantity); view.setTag(viewHolder); }else{ viewHolder= (ViewHolder)convertView.getTag(); } 
 public class AndroidListViewActivity extends ListActivity { private ListView listView; private String names[] = { "HV CAPACITOR", "LV CAPACITORCSS", }; private String desc[] = { "The Powerful Hypter Text Markup Language 5", "Cascading Style Sheets", }; private Integer imageid[] = { R.drawable.hv_capacitor, R.drawable.lv_capacitor, }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.capacitor_layout); // storing string resources into Array String[] product_name = getResources().getStringArray(R.array.product_name); // Binding Array to ListAdapter this.setListAdapter(new ArrayAdapter(this, R.layout.list_item, R.id.label, product_name)); ListView lv = getListView(); // listening to single list item on click lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { // selected item String product = ((TextView) view).getText().toString(); // Launching new Activity on selecting single List Item Intent i = new Intent(getApplicationContext(), SingleListItem.class); // sending data to new activity i.putExtra("product", product); startActivity(i); } }); CapacitorList capacitorList = new CapacitorList(this, names, desc, imageid); listView = (ListView) findViewById(R.id.listView); listView.setAdapter(capacitorList); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { // Launching new Activity on selecting single List Item Intent i = new Intent(getApplicationContext(), CapacitorList.class); // sending data to new activity // startActivity(i); @Override public void onItemClick(AdapterView< ?> adapterView, View view, int i, long l) { Toast.makeText(getApplicationContext(), "You Clicked " + names[i], Toast.LENGTH_SHORT).show(); } }); } @Override public boolean onCreateOptionsMenu (Menu menu){ // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected (MenuItem item){ // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } 
  • Как изменить цвет элементов ListView в фокусе и щелчке
  • Как обращаться с ListView на Android
  • Элемент списка подобъектов ListView clickable confilct
  • ListView в ArrayAdapter order get смешивается при прокрутке
  • Как динамически обновлять ListView на Android
  • Проблема при использовании пользовательского шрифта - «родной шрифт не может быть создан»
  • Обнаружение выбранного элемента (в ListView) порождало ContextMenu (Android)
  • Android ListView с флажком и всеми интерактивными
  • Ленивая загрузка изображений в ListView
  • Пользовательский адаптер для просмотра списка
  • Как обрабатывать несколько таймеров обратного отсчета в ListView?
  • Interesting Posts

    Есть ли бесплатный способ контролировать последовательный порт в Windows 7 x64?

    jQuery: как вызвать событие клика привязки ссылки

    Поиск excel с двумя поисковыми словами (множественный поиск) с использованием макроса vba

    Как открыть случайный файл в папке и установить, должны ли открываться только файлы с указанными расширениями имен файлов?

    Как мне вызвать controller / методы просмотра с консоли в Rails?

    Хорошие инструменты для создания анализатора / анализатора C / C ++

    Точность использования оперативной памяти Windows 8 Task Manager

    typedef указатель const weirdness

    Должен ли я снять аккумулятор ноутбука?

    Почему реализация и объявление classа шаблона должны быть в одном заголовочном файле?

    Угловой HttpPromise: разница между методами `success` /` error` и аргументами `then`

    Разрешения на доступ к файлам IIS AppPoolIdentity и файловой системы

    Неисправность Matrox TH2G Digital на графическом процессоре Intel HD 5500 (обнаруживает сигнал VGA как DisplayPort, обеспечивает низкое разрешение)

    Как мы можем запретить Службе убивать ОС?

    Как отсортировать список по алфавиту?

    Давайте будем гением компьютера.