#android #listview #android-cursoradapter
#Android #listview #android-cursoradapter
Вопрос:
Справочная информация: Я пытаюсь внедрить систему обмена сообщениями в своем приложении, и я пишу пользовательский CursorAdapter
для отображения сообщений в ListView
окне чата. Я хочу использовать другой макет строки для входящих и исходящих сообщений (информация, которая сохраняется в строке SQLite в курсоре). В каждой строке есть одинаковые элементы с одинаковыми идентификаторами, но они расположены по-разному.
Проблема: В настоящее время я переопределил newView()
и bindView()
. Когда ListView
сначала заполняется, он создает все View
s идеально, проверяя каждую строку, чтобы увидеть, является ли она входящей или исходящей, и раздувает соответствующий XML-файл. Однако, когда я прокручиваю или в окно добавляется новое сообщение, адаптер повторно использует View
s для неправильных строк. Я бы переопределил getView()
, но это не передается Cursor
в качестве параметра, поэтому у меня нет способа узнать, должна ли строка быть входящей или исходящей.
Я не ищу код, а скорее какое-нибудь предложение по элегантной реализации. Заранее спасибо!
Комментарии:
1. Как долго вы ожидаете, что эти списки будут увеличиваться? Если они занимают более нескольких страниц, отказ от повторного использования просмотров может вызвать проблемы с прокруткой / производительностью.
2. Им нужно поддерживать довольно длинные списки сообщений, поэтому я определенно хотел бы переработать.
Ответ №1:
Вот два возможных решения:
(1) Используйте единый макет для всех элементов, который вы можете настроить при привязке для отображения по желанию. Самым простым способом было бы просто использовать корневой вид в виде FrameLayout, который содержит N дочерних элементов для каждого из разных состояний, и вы делаете одно из них видимым, а все остальные исчезают при привязке. Конечно, вы хотите позаботиться о том, чтобы это не привело к увеличению количества просмотров ваших элементов, которые они содержат.
(2) Реализовать Adapter.getItemViewType()http://developer.android.com/reference/android/widget/Adapter.html#getItemViewType (int), чтобы сообщить представлению списка о различных типах элементов, которые у вас есть, чтобы оно использовало правильный.
Комментарии:
1. Хотя второй ответ немного расширяет предложение Боба, мне действительно нравится ваше первое предложение. Я думаю, что я собираюсь пойти по этому пути. Спасибо!
2. Для потомков я добился того, чего хотел, создав очень простой двухуровневый макет с 3 дочерними элементами в
RelativeLayout
. Затем я применяю другойRelativeLayout.LayoutParams
к макету вbindView()
.
Ответ №2:
Всего лишь несколько мыслей, лично я нахожу всю комбинацию ListView
и CursorAdapter
немного … ошибочной… раздутый — правильное слово? Было бы проще иметь комбинацию ScrollView
/ LinearLayout
, которая просто добавит соответствующую TextView
по запросу?
Но что касается вашего решения, поскольку пользователь, похоже, не может изменить порядок сообщений по мере их добавления, вы могли бы добавить ArrayList<String>
поле в свой пользовательский CursorAdapter
, которое будет отслеживать, являются ли сообщения входящими или исходящими. Что-то вроде:
private ArrayList<String> cursorMonitor; //"incoming" and "outgoing" as your options.
… и затем внутри, где бы ListView
ни заполнялся, просто используйте
cursorMonitor.add(my_cursor.getString("outgoing_or_incoming"));
И затем в getView()
вы можете переопределить его и использовать cursorMonitor
, чтобы определить, какой макет вам нужно увеличить.