Android ViewView просмотра. когда его использовать, а когда нет - PullRequest
8 голосов
/ 09 июля 2010

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

Ответы [ 3 ]

10 голосов
/ 09 июля 2010

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

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

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

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

    private static class ViewHolder {
    
            protected TextView itemName;
    
        }
    

В Получить метод просмотра

    @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 ");
    }

Важно: И мы не должны устанавливать какие-либоТег для объекта просмотра, кроме объекта-виджета

1 голос
/ 09 июля 2010

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

ДО:

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);
...