Android listview viewholder. Когда его использовать, а когда нет

У меня есть ListView с адаптером пользовательского списка. В методе getView () я использую шаблон «ViewHolder», как показано в API Demos для ListView14.java. Когда я сначала выдаю список, он, похоже, правильно загружается. Однако проблема, с которой я сталкиваюсь, заключается в том, что когда я просматриваю список, я вижу, что данные для списка отображаются в неправильных строках (например, TextView, который должен быть в строке 10, отображается в строке 2, например ). Однако, когда я не использую зрителя и вместо этого вызываю findViewById () каждый раз, тогда представление списка отображается правильно.

Однако проблема, с которой я сталкиваюсь, заключается в том, что когда я просматриваю список, я вижу, что данные для списка отображаются в неправильных строках (например, TextView, который должен быть в строке 10, отображается в строке 2, например ).

Скорее всего, вы неправильно перерабатываете свои строки, так что ViewHolders вы управляете, не являются правильными для строки, которую вы возвращаете.

Вот бесплатная выдержка из одной из моих книг, в которой больше говорится о переработке строк – возможно, это поможет вам определить, где все идет не так.

  • Я столкнулся с такой же проблемой
  • Решается с использованием ниже техник
  • Причина: адаптер не загружается часто.
  • В классе Custom Adapter добавьте ViewHolder с помощью спецификаторов доступа

     private static class ViewHolder { protected TextView itemName; } 

В методе Get View

  @Override public View getView(int position, View view, ViewGroup viewGroup) { // create a ViewHolder reference ViewHolder holder; //check to see if the reused view is null or not, if is not null then reuse it if (view == null) { holder = new ViewHolder(); view = mLayoutInflater.inflate(R.layout.list_item, null); holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view); // the setTag is used to store the data within this view view.setTag(holder); } else { // the getTag returns the viewHolder object set as a tag to the view holder = (ViewHolder)view.getTag(); } // now Use Holder object toget Idss holder.itemName.setText(" sample text based on position "); } 

Важно: И мы не должны устанавливать Any Tag для объекта view, кроме объекта Viewholder

Поэтому я думаю, что я обнаружил реальную проблему здесь. Когда вы устанавливаете параметры макета на лету для каждой строки, вам нужно убедиться, что вы делаете это для всех условий. Моя проблема заключалась в том, что если это была первая строка, я задал параметр макета (например, заполнение или поля и т. Д.), Но если бы это была средняя строка, я явно не задал эти параметры, думая, что он просто будет использовать то, что было завышено По мнению надувных. Это объясняет, почему это срабатывало, когда я каждый раз раздувал представление. Вот до и после:

ДО:

 if (position == 0) { layoutParams.topMargin = uiHelper.getDip(15.0f); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE); holder.actionMenu.setLayoutParams(layoutParams); holder.contentLayout.setBackgroundResource(R.drawable.top_row); } else if (position == posts.size() - 1) { holder.contentLayout .setBackgroundResource(R.drawable.bottom_row); holder.contentLayout.setPadding(holder.contentLayout .getPaddingLeft(), holder.contentLayout.getPaddingTop(), holder.contentLayout.getPaddingRight(), holder.contentLayout.getPaddingBottom() + uiHelper.getDip(10.0f)); } else { holder.contentLayout .setBackgroundResource(R.drawable.inner_row); } 

ПОСЛЕ: `

  layoutParams.topMargin = uiHelper.getDip(10.0f); holder.contentLayout.setPadding(holder.contentLayout .getPaddingLeft(), holder.contentLayout.getPaddingTop(), holder.contentLayout.getPaddingRight(), uiHelper.getDip(10.0f)); if (position == 0) { layoutParams.topMargin = uiHelper.getDip(15.0f); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE); holder.contentLayout.setBackgroundResource(R.drawable.top_row); } else if (position == posts.size() - 1) { holder.contentLayout .setBackgroundResource(R.drawable.bottom_row); holder.contentLayout.setPadding(holder.contentLayout .getPaddingLeft(), holder.contentLayout.getPaddingTop(), holder.contentLayout.getPaddingRight(), uiHelper.getDip(20.0f)); } else { holder.contentLayout .setBackgroundResource(R.drawable.inner_row); } holder.actionMenu.setLayoutParams(layoutParams); 
Intereting Posts
«Незарегистрированное приложение» показано на экране согласия в Google+ Прослеживание кампании Google Analytics не отображается в отчете Как повторно использовать объекты RecipeViewView, адаптеры и держатели Распространение «бесплатного» приложения для Android в виде файла .apk напрямую Могут ли Windows Phone 8 и Android подключиться через Wifi Direct? Невозможно преобразовать строку '@ bool / some_key' в целевой класс 'boolean' Как создать шаблонный проект для Android Studio Как сгенерировать отчет о покрытии кода для androidTest с использованием Jacoco в студии android Добавление изображения в текстовый фон текста Как скомпилировать C в исполняемый двоичный файл и запустить его в Android из Android Shell? Как отключить приложение из учетной записи Google Диска Заменить макет на изменение ориентации Camera.Parameters, специфичный для устройства (Samsung S3 Mini) Прокрутка больших списков адаптеров на основе курсора выполняется быстрее, чем гораздо меньшие списки адаптеров в памяти Преимущества компиляции кода C с интерфейсом gcc gcc на C ++