Андроид. Как работает метод 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()
способ также.