Андроид. Как работает метод notifyDataSetChanged () и ListViews?

Я пытаюсь понять ListView концепция и как она работает, и я пытаюсь создать свой собственный адаптер, который расширяет BaseAdapter. Для ArrayAdapter например, есть notifyDataSetChanged() метод, который должен быть вызван после обновления списка массивов, который содержит все ваши данные, чтобы обновить ListView.

но я создаю свой собственный подкласс BaseAdapter. Этот метод мне недоступен или нет? Как реализовать этот метод? В принципе, что делает этот метод вот именно, может быть, тогда я пойму.

в случае ArrayAdapter Я предполагаю, что он смотрит на какую позицию ListView в настоящее время отображается, и он проверяет, является ли он таким же, как в ArrayList после того, как он был обновлен? Или...

в нем говорится, что метод:

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

но как именно это происходит обновить себя?

может кто-нибудь объяснить, пожалуйста?

4 ответов


я понял. Я не мог понять, как, черт возьми, начался адаптер и как он узнал, откуда получить данные. Когда я расширил BaseAdapter класс, в конструкторе этого класса я инициализировал список элементов, которые я хотел видеть в ListView. Но я не мог понять, как эти значения будут использоваться и когда.

так вот в чем дело !!! :

на BaseAdapter есть некоторые методы, которые должны быть переопределенный. Среди них есть getCount().

когда ListView создается и еще много чего, он вызывает getCount(). Если это возвращает значение, отличное от 0 (я вернул размер ArrayList, который я ранее инициализировал в конструкторе), то он вызывает getView() достаточное количество раз, чтобы заполнить экран с элементами. например, я инициализировал ArrayList С 20 пунктов. Потому что только 8 предметов изначально помещаются на экране,getView() был вызван 8 раз, каждый раз спрашивая позиция, которую мне нужно было вернуть (точнее, он хотел знать, как строка будет выглядеть в списке на этой конкретной позиции, какие данные она должна содержать). Если прокрутить список вниз,getView() вызывается снова и снова, пока я не достигну конца списка, в моем случае 20 элементов / строк.

что notifyDataSetChanged() делает ... при вызове он смотрит, какие элементы отображаются на экране в момент его вызова (точнее, какие индексы строк ) и вызывает getView() с этими позициями.

то есть если вы отображаете первые 8 элементов в списке (так что это те, которые видны на экране), и вы добавляете другой элемент между 2-м и 3-м элементом в списке, и вы вызываете notifyDataSetChanged() затем getView() вызывается 8 раз, причем позиции начинаются с 0 и заканчиваются на 7, а потому в getView() метод вы получаете данные из ArrayList затем он автоматически вернет новый элемент, вставленный в список вместе с 7 из предыдущий 8 (7, а не 8, потому что последний элемент пошел на одну позицию вниз, поэтому он больше не виден), и ListView будет перерисовываться или что-то еще с этими элементами.

кроме того, важно указать, что если вы используете getView() правильно, вы закончите переработку элементов (объектов), уже отображаемых (вместо создания новых). См.видео около 12: 00 минут, чтобы увидеть правильный способ реализации getView()

я понял все это, сделав звонки в LogCat в каждом методе и после того, что происходило.

надеюсь, это поможет кому-то, кто только сейчас начинает понимать, как ListView s работа.

П. С. также помогли мне многое понять.


BaseAdapter может "наблюдаться" другими классами. Когда вы вызываете метод ListView это registerDataSetObserver адаптер. Таким образом, адаптер знает, кто заинтересован в новых данных.

вы можете проверить источник BaseAdapter здесь. Он довольно маленький.

notifyDataSetChanged is доступно для вас, и вы в основном не должны переопределять его (потому что он не делает ничего особенного, поэтому вы можете просто использовать его в своем собственном классе).


Предположим ваш ListView отображает некоторые данные, хранящиеся в ArrayList.

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

вот здесь notifyDatasetChanged() приходит. Он говорит ListView, что данные были изменены; и чтобы показать новые данные,ListView должно быть переписано.


Как вы расширяете BaseAdapter для вашего собственного для создания подкласса вы получите notifyDataSetChanged() способ также.