ListView getChildAt возвращает null для видимых детей

Я получаю странное поведение из метода listview / getChildAt.

У меня есть HashSet, iconsToUpdate, значков, которые были изменены в базе данных. Я хочу перебирать видимые строки, чтобы увидеть, нужно ли обновлять их значки, чтобы отображать новые значки. Мне не нужно проверять значки, которые в настоящее время не отображаются, поскольку они будут правильно отображены при визуализации.

Моя проблема в том, что getChildAt возвращает null, когда кажется, что он не должен. Я знаю, что getChildAt может только возвращать просмотры, которые в настоящее время видны, но он возвращает null для некоторых видимых строк.

Вот мой код, который выполняет итерацию по видимым строкам:

Logger.debug("First visible index: " + f_listView.getFirstVisiblePosition()); Logger.debug("Last visible index: " + f_listView.getLastVisiblePosition()); for (int i = f_listView.getFirstVisiblePosition(); i <= f_listView.getLastVisiblePosition(); i++) { String tag = "asdf"; // Remove when bug is fixed. if (f_listView == null) { Logger.debug("f_listView is null"); } else if (f_listView.getChildAt(i) == null) { Logger.debug("Child at index " + i + " is null"); } else { tag = (String) f_listView.getChildAt(i).getTag(); Logger.debug("Successful at index " + i + ", tag is: " + tag); } if (iconsToUpdate.contains(tag)) { setIcon(i, f_aim.getInHouseIcon(tag)); } } 

Вот журнал, соответствующий запуску этого цикла:

 D/...: First visible index: 3 D/...: Last visible index: 8 D/...: Successful at index 3, tag is: ... D/...: Successful at index 4, tag is: ... D/...: Successful at index 5, tag is: ... D/...: Child at index 6 is null D/...: Child at index 7 is null D/...: Child at index 8 is null 

Следует отметить, что первый и последний видимые индексы сообщаются правильно, так как я просматриваю строки 3-8, когда я запускаю это. Строки 6, 7, 8 отображаются правильно. Как они отображаются, если они являются нулевыми?

Кроме того, я не знаю, важно ли это, но строка 5 является последней видимой строкой, когда я нахожусь в верхней части списка.

Любая информация о том, почему эти строки возвращаются как null, будет с большой благодарностью.

Благодаря!

Solutions Collecting From Web of "ListView getChildAt возвращает null для видимых детей"

ListView.getChildAt (i) работает, где 0 – первая видимая строка, и (n-1) – последняя видимая строка (где n – количество видимых видов, которые вы видите).

Получайте последний / первый видимый результат в позиции вашего адаптера данных. Итак, с тех пор, как вы начинаете в позиции 3, с тем, что выглядит как 6 видимых просмотров, вот когда вы получаете позиции 6-8, вы получаете нулевое значение.

В вашем примере getChildAt (0) вернет позицию 3. То, что я обычно делаю, – это сохранить позицию в моих представлениях, чтобы позже я мог искать свой файл данных, если мне нужны значения.

Я думаю, что ваш цикл for должен выглядеть так:

 for (int i = 0; i <= f_listView.getLastVisiblePosition() - f_listView.getFirstVisiblePosition(); i++) 

Надеюсь это поможет.

Пытаться

 f_listView.getChildAt(positionOfChildYouWantGet - f_listView.getFirstVisiblePosition()); 

Когда вы вызываете listView1.getLastVisiblePosition() и listView1.getFirstVisiblePosition() , listview возвращает позиции элементов, которые частично отображаются в списке. Например, первый элемент может быть наполовину видимым, а последний элемент может быть наполовину видимым. В этом случае, даже если вы видите часть элемента в списке, адаптер еще не вызвал getView() для элемента, и поэтому элемент по-прежнему считается нулевым.

В моем случае у меня есть listView и первый элемент полностью видимый, но когда я делаю getFirstVisiblePosition() результат равен 1!

Это становится более странным, когда я прокручиваю и делаю первый элемент наполовину видимым, тогда мой getView показывает, что getFirstVisiblePosition() равно 0.

Это мой код:

 public View getView(final int position, View convertView, final ViewGroup parent) { row = convertView; final AtomPaymentHolder holder = new AtomPaymentHolder(); LayoutInflater inflater = ((Activity) context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); row.setTag(items.get(position)); holder.songitem = items.get(position); final int firstPosition = MainActivity.listviewSong.getFirstVisiblePosition() - MainActivity.listviewSong.getHeaderViewsCount(); final int lastPosition = MainActivity.listviewSong.getLastVisiblePosition(); if(MusicService.indexService>= firstPosition && MusicService.indexService<= lastPosition){ MainActivity.listviewSong.getChildAt(MusicService.indexService-firstPosition).setBackgroundColor(getContext().getResources().getColor(R.color.pressed_color)); } 

(Когда я выбрал следующий элемент и прокрутку, он работает хорошо)

Возможно, они частично видны. Но когда getView () пытается переработать представления, они получают ПОЛНОСТЬЮ видимые, другие принимают их как null. Например, если вы прокручиваете список, и верхний элемент частично виден, а нижняя часть частично видима, поэтому они являются нулями, но вы все еще видите их.

Я пробовал когда-нибудь в OnListItemClickListener (), но терпел неудачу. Наконец, я внес некоторые изменения в свой адаптированный адаптер для listview. Здесь, в getView (), я применяю clickListener к элементу, который я часто добавлял в список. N выполняйте все необходимые функции. Вот мой код, где я добавляю Image View в список n, так что применяйте прослушиватель к imageview.

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

В getView () настраиваемого адаптера // ——————————— code ——- ———————————–


LayoutInflater inflater = (LayoutInflater) контекст
.getSystemService (Context.LAYOUT_INFLATER_SERVICE);

View rowView = inflater.inflate(R.layout.icon_image_layout, parent, false); ImageView imageView = (ImageView) rowView.findViewById(R.id.Icon_ImageView); imageView.setClickable(true); final int pos=position; imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub // TODO Auto-generated method stub try{ if(previous_view!=null) previous_view.setBackgroundColor(Color.WHITE); }catch (Exception e) { System.out.println("Exception Occurs Previous View"); } v.setBackgroundColor(Color.RED); MainActivity.imageView.setImageResource(MainActivity.Image_Name[pos]); previous_view=v; return false; } });

Разве это не потому, что вы говорите

 f_listView.getChildAt(i) 

И вы должны получать элемент в этой позиции?

 f_listView.getItemAtPosition(i)