понедельник, 17 сентября 2012 г.

Принудительная инвалидация видов в списках

ListView в Android, как известно, устроены с небольшой хитростью, эта хитрость — ListView Recycler. Приницип Recycler'а, если кратко, состоит в том, что если в списке элементов больше, чем вмещается на экран, при прокручивании списка виды новых элементы не создаются, а переиспользуются виды старых — на этом приниципе работают имплементации getView в адаптерах.

Если в какой-то момент требуется обновить (инвалидировать) конкретный известный вид элемента (или даже его дочерний вид) списка в то время, когда он видим на экране, можно вызвать ListView.invalidate() или Adapter.notifyDataSetChanged(), но иногда эти методы нерационально обновляют и соседние виды, а то и вообще все видимые (особенно если layout построен неправильно). Есть способ получить текущий вид элемента списка используя метод ListView.getChildAt(position). Однако position в данном случае это не индекс элемента в списке, как можно было бы ожидать, а индекс относительно видимых на экране видов. Поэтому полезными будут такие методы:

public static View getItemViewIfVisible(AdapterView<?> holder, int itemPos) {
int firstPosition = holder.getFirstVisiblePosition();
int wantedChild = itemPos - firstPosition;
if (wantedChild < 0 || wantedChild >= holder.getChildCount()) return null;
return holder.getChildAt(wantedChild);
}

public static void invalidateByPos(AdapterView<?> parent, int position) {
final View itemView = getItemViewIfVisible(parent, position);
if (itemView != null) itemView.invalidate();
}

invalidateByPos обновляет вид только если он видим на экране (насильно вызывая getView адаптера), а если элемент не видим — getView адаптера будет вызван автоматически когда этот вид появится в области видимости при прокрутке списка. Чтобы обновить некий дочерний вид элемента, вы можете использовать метод getViewIsVisible, он вернёт вид элемента из которого можно получить доступ к его дочерним видам и null, если вид не видим пользователю и в обновлении нет необходимости.
Методы описаны в классе: Utils

Комментариев нет:

Отправить комментарий