Вопрос по android-adapterview, android-listview, android – Android. Как работает метод notifyDataSetChanged () и ListViews?

55

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

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

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

Это говорит о том, что метод:

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

Но как именно он обновляется?

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

Ваш Ответ

4   ответа
9

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

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

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

Так когдаnotifyDatasetChanged() называется я заставляю ListView вызватьgetView() метод для текущих элементов, отображаемых на экране? AndreiBogdan
чувак, где ты был Почему вы удалили комментарий? хе-хе Теперь, похоже, я разговариваю сам с собой. AndreiBogdan
И когда вы вызываете notifyDatasetChanged (), он снова перерисовывает весь список, а не только какой-то конкретный вид. На самом деле, invalidate () также делает нечто похожее на это.
@AndreiBogdan извините, это не правильно (я неправильно понял ваш вопрос).
Ну, это то, что я не получаю. Где мне сообщить адаптеру, что я использую определенный ArrayList для хранения данных? Когда я использую ArrayAdapter, да, я отправляю ссылку на ArrayList, когда я связываю адаптер с ListView, но как насчет того, когда я расширяю BaseAdapter? Как узнать, что значения взяты из моего ArrayList? AndreiBogdan
0

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

13

BaseAdapter можно «наблюдать» другими классами. Когда вы вызываете методListView setAdapter() это звонкиregisterDataSetObserver адаптера. Итак, адаптер знает, кого интересуют новые данные.

Вы можете проверить источникBaseAdapter Вот, Это довольно мало.

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

Как связать мой адаптер с моим списком рассылки?
Я думаю, что это наиболее "точечный" ответ на вопрос.
Это должен быть принятый ответ!
179

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

So here's the thing !!! :

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

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

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

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

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

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

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

ПостскриптумЭтот пример также очень помог мне понять.

Ну, это хорошее объяснение. Но мы подумали, что вы знаете, как работает ListView.
Это одно из лучших объяснений, с которыми я столкнулся! супер вещи!
Because only 8 items initially fit on the screen, getView() was called 8 times, Это не всегда верно, так как адаптер может вызывать некоторые дополнительныеgetViews для измерения.
отличное объяснение :), хотелось бы дать больше, чем 1 голос.
Рад, что это помогло. AndreiBogdan

Похожие вопросы