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, будет с благодарностью.
Спасибо!
Ответы
Ответ 1
listView.getChildAt(i) работает там, где 0 - первая видимая строка, а (n-1) - последняя видимая строка (где n - количество видимых видов, которые вы видите).
Получите последний/первый видимый результат в позиции вашего адаптера dataAdapter. Итак, с тех пор, как вы начинаете с позиции 3, с тем, что выглядит как 6 видимых просмотров, что при получении для позиций 6-8 вы получаете нулевое значение.
В вашем примере getChildAt (0) вернет позицию 3. То, что я обычно делаю, это сохранить позицию в моих представлениях, чтобы затем я мог искать свой файл данных позже, если мне нужны значения.
Я думаю, что ваш цикл for должен выглядеть так:
for (int i = 0; i <= f_listView.getLastVisiblePosition() - f_listView.getFirstVisiblePosition(); i++)
Надеюсь, что это поможет.
Ответ 2
Try
f_listView.getChildAt(positionOfChildYouWantGet - f_listView.getFirstVisiblePosition());
Ответ 3
Когда вы вызываете listView1.getLastVisiblePosition()
и listView1.getFirstVisiblePosition()
, listview
возвращает позиции элементов, которые частично отображаются в списке. Например, первый элемент может быть наполовину видимым, и последний элемент может быть наполовину видимым. В этом случае, даже если вы видите часть элемента в списке, адаптер еще не вызвал функцию getView()
для элемента, и поэтому элемент по-прежнему считается нулевым.
Ответ 4
В моем случае у меня есть 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));
}
(когда я выбрал следующий элемент и прокрутку, он работает хорошо)
Ответ 5
Возможно, они частично видимы. Но когда getView() пытается переработать представления, они становятся полностью видимыми, другие принимают их как null. например, если вы прокручиваете список, и верхний элемент частично виден, а нижняя часть частично видима, поэтому они являются нулями, но вы все еще видите их.
Ответ 6
Я пробовал когда-нибудь в OnListItemClickListener(), но терпел неудачу. Наконец, я внес некоторые изменения в свой адаптированный адаптер для listview. Здесь, в getView(), я применяю clickListener к элементу, который я часто добавлял в список. n выполняйте все необходимые функции. Вот мой код, где я добавляю Image View в список n, так что применяйте прослушиватель к просмотру изображения.
Думаю, это поможет тем, кто хочет изменить цвет, когда выбран определенный элемент списка. Пойдите для этого..
В getView() настраиваемого адаптера
// ---------------------------------код-------------- ----------------------------
Контекст 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;
}
});
Ответ 7
Разве это не потому, что вы говорите
f_listView.getChildAt(i)
И вы должны получать элемент в этой позиции?
f_listView.getItemAtPosition(i)