Так что у меня есть проблема, с которой я сталкивался раньше, и, естественно, я попросил помощи здесь . Ответ Luksprog был великолепен, потому что я понятия не имел о том, как ListView и GridView оптимизировали себя с помощью повторного использования Views. Так что с его советом я смог изменить способ добавления Views в мой GridView. Проблема сейчас в том, что у меня что-то не имеет смысла. Это моё getView
из моих BaseAdapter
:
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.day_view_item, parent, false);
}
Log.d("DayViewActivity", "Position is: "+position);
((TextView)convertView.findViewById(R.id.day_hour_side)).setText(array[position]);
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.day_event_layout);
//layout.addView(new EventFrame(parent.getContext()));
TextView create = new TextView(DayViewActivity.this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 62, getResources().getDisplayMetrics()), 1.0f);
params.topMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
params.bottomMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
create.setLayoutParams(params);
create.setBackgroundColor(Color.BLUE);
create.setText("Test");
//the following is my original LinearLayout.LayoutParams for correctly setting the TextView Height
//new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()), 1.0f)
if(position == 0) {
Log.d("DayViewActivity", "This should only be running when position is 0. The position is: "+position);
layout.addView(create);
}
return convertView;
}
}
Проблема в том, что когда я прокручиваю, это происходит, а не в позиции 0 ... Похоже на позицию 6 и позицию 8, плюс это ставит два в позицию 8. Теперь я все еще пытаюсь освоить использование ListView и GridView, поэтому я делаю не понимаю, почему это происходит. Одна из основных причин, по которой я задаю этот вопрос, - помочь тем, кто, возможно, не знает о перерабатывающем View ListView и GridView, или, как говорится в этой статье , механизм ScrapView.
Позже Править
Добавление ссылки на Google IO talk - это практически все, что вам нужно, чтобы понять, как работает ListView. Ссылка была мертвой в одном из комментариев. Так что user3427079 был достаточно хорош, чтобы обновить эту ссылку. Здесь это для легкого доступа.
0
).ListView
потребуется показать новую строку (например, продолжая прокручивать вниз / вверх). Проблема в том, что представление, которое только что исчезло и которое будет использоваться на будущих должностях,TextView
уже добавило к нему, это проблема. Чтобы решить это, вы должны удалить его вgetView
методе, еслиgetView
метод вызывается для любой другой позиции, кроме0
.Ответы:
Вначале я также не знал об утилизации списков и механизме использования convertview, но после целого дня исследований я в значительной степени понимаю механизмы представления списков, ссылаясь на изображение из android.amberfog
Всякий раз, когда ваше представление списка заполняется адаптером, оно в основном показывает количество строк, которое список может отображать на экране, и количество строк не увеличивается даже при прокрутке списка. Это трюк, который использует Android, чтобы listview работал более эффективно и быстро. Теперь, как вы можете видеть, внутренняя история просмотра списка, ссылающегося на изображение, первоначально у списка просмотра было 7 видимых элементов, затем, если вы прокрутите вверх, пока элемент 1 больше не будет виден, getView () передает это представление (т.е. item1) переработчик и вы можете использовать
внутри вашего
В вашей logcat вы заметите, что convertview является нулевым для всех видимых строк, потому что изначально в утилите не было представлений (т.е. элементов), поэтому ваш getView () создает новое представление для каждого из видимых элементов, но как только вы прокрутите вверх и элемент 1 выйдет из экрана, он будет отправлен в Recycler с его текущим состоянием (например, TextView 'text' или в моем случае, если флажок установлен, он будет связан с представлением и хранится в утилизаторе).
Теперь, когда вы прокручиваете вверх / вниз, ваше представление списка не будет создавать новое представление, оно будет использовать представление, которое находится в вашем утилизаторе. В вашем Logcat вы заметите, что 'convertView' не является нулевым, потому что ваш новый элемент 8 будет нарисован с использованием convertview, то есть, в основном, он берет представление элемента 1 из переработчика и надувает элемент 8 вместо него, и вы можете наблюдать что в моем коде. Если у вас был флажок, и если вы отметили его в позиции 0 (скажем, у item1 был флажок, и вы отметили его), поэтому, когда вы прокрутите вниз, вы увидите, что флажок элемента 8 уже установлен, поэтому listview снова использует тот же вид, не создает для вас нового из-за оптимизации производительности.
Важные вещи
1 . Никогда не устанавливайте для
layout_height
andlayout_width
вашего списка представлениеwrap_content
as,getView()
что заставит ваш адаптер получить какой-либо дочерний элемент для измерения высоты представлений, которые будут отображаться в виде списка, и может вызвать неожиданное поведение, например, возвращать convertview, даже если список не прокручивается. Всегда используетсяmatch_parent
или исправляется ширина высота.2 . Если вы хотите использовать какой-либо макет или представление после представления списка, вам могут прийти в голову вопросы, если я задаю
layout_height
дляfill_parent
представления представление после того, как представление списка не будет отображаться при переходе вниз по экрану, поэтому лучше поместить представление списка внутри макет. Например, Linear Layout и установите высоту и ширину этого макета в соответствии с вашими требованиями и присвойте атрибуту height и width вашего просмотра списка ваш макет (например, если ширина макета равна 320, а высота равна 280), то ваш просмотр списка должны иметь одинаковую высоту и ширину, Это скажет getView () о точной высоте и ширине представлений, которые будут отображаться, и getView () не будет снова и снова вызывать некоторые случайные строки, и другие проблемы, такие как возвращение представления преобразования даже до того, как прокрутка не произойдет, у меня есть тест это само по себе, если мой просмотр списка не был внутри lineaLayout, у него также были проблемы, такие как повторение вызова представления и преобразование представления, так как помещение Listview внутри LinearLayout работало для меня как волшебство (не знаю почему)Но теперь это решено, я знаю, я не так хорош в объяснении, но, как я потратил весь свой день, чтобы понять, я думал, что другие новички, как я, могут получить помощь из моего опыта, и я надеюсь, что теперь вы, люди, будете иметь немного понимания структуры ListView, как это работает, поскольку это действительно грязно и хитро, поэтому новички нашли слишком много проблем с пониманием этого
источник
if you had a checkbox and if you check it at position 0(let say item1 has also a checkbox and you checked it) so when you scroll down you will see item 8 checkbox is already checked,this is why listview is re using the same view not creating a new for you due to performance optimization.
чтобы я осознал свою ошибку. Лучший пост о переработке Android ListView, с которым я сталкивался!RecyclerView
на том же механизме? В моем вопросе stackoverflow.com/questions/47897770/… я знаю, что задача практически невозможнаlistView
. Должен ли я попробовать сrecyclerView
?Будьте внимательны, в паттерне Holder, если вы устанавливаете положение в вашем объекте Holder, вы должны устанавливать его каждый раз, например:
это пример из абстрактного класса, где
выполняет все операции настройки для
источник
parent.setTag(holder);
вместо правильного пути, который есть,view.setTag(holder);
Используя шаблон Holder, вы можете достичь того, что вы хотите:
Вы можете найти описание этой модели здесь:
Повторное использование представления списка происходит, когда вы прокручиваете экран вниз, и вышеупомянутые элементы представления списка скрыты. Они повторно используются для отображения новых элементов списка.
источник