#android #listview #adapter
#Android #listview #адаптер
Вопрос:
У меня есть ListView с заголовком, установленным с помощью ListView.addHeader(...)
Похоже, что он работает просто отлично, за исключением случаев, когда вы пытаетесь создать контекстное меню.
Когда пользователь долго нажимает строку, позиция в onCreateContextMenu
обратном вызове, похоже, отключена на единицу. Когда пользователь долго нажимает на заголовок, сообщаемая позиция равна 0 (я бы не ожидал обратного вызова), когда пользователь долго нажимает на первую строку, сообщаемая позиция равна 1 вместо 0 и так далее.
Тот же код работает, как ожидалось, без заголовка.
Я знаю, что внутренне Android просто создает новый адаптер вокруг моего, когда я устанавливаю заголовок, но я бы предположил, что они обрабатывают настройку позиции перед вызовом обратных вызовов.
Это то, что я вижу ожидаемое поведение? Возможно, я делаю что-то не так?
Вот как я извлекаю позицию:
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
int position = info.position;
// this is my workaround, but I'm afraid it's going to bite me in
// the ass if/when GOOG fixes this
if( this.hasHeader() amp;amp; position > 0 ) position--;
Ответ №1:
Я знаю, что внутренне Android просто создает новый адаптер вокруг моего, когда я устанавливаю заголовок, но я бы предположил, что они обрабатывают настройку позиции перед вызовом обратных вызовов.
Я сомневаюсь в этом. Я не пробовал это конкретное поведение, но, написав адаптеры для переноса самостоятельно, это нелегко решаемая проблема.
Проще говоря, содержимое контекстного меню вообще не включает Adapter
, только AdapterView
. Следовательно, у переноса нет возможности Adapter
либо использовать события меню, либо корректировать значения позиций.
Я подозреваю, что вам просто нужно будет вычесть 1
и игнорировать строку заголовка самостоятельно.
Комментарии:
1. Спасибо. Таким образом,
AdapterView
передается положение представлений , но адаптер фактически передает значения индекса фактических элементов списка, независимо от того, установлен заголовок или нет? Я думаю, что понимаю, о чем вы говорите, но это развеет мои сомнения, если вы знаете какую-либо документацию, которая объясняет, как настройка заголовка влияет на позицию в объектах AdapterContextMenuInfo. Мой поиск ничего конкретно об этом не дал.2. @psychotik: «Итак, AdapterView обходит позиции представлений, но адаптер фактически обходит значения индексов фактических элементов списка, независимо от того, установлен заголовок или нет?» —
AdapterView
думаетposition
, что будет выполняться от0
до того, чтоAdapter
возвращает дляgetCount()
минуса1
. Точка. Совершенно не обращая внимания на то, что это значит.ListView
заменяетAdapter
другим (перенос)Adapter
. ПереносAdapter
знает, что позиция0
является заголовком иgetCount()
должна увеличиваться на1
.3. @psychotik: «если вы знаете какую-либо документацию, которая объясняет, как настройка заголовка влияет на позицию в объектах AdapterContextMenuInfo» — я сомневаюсь, что есть что-либо, кроме исходного кода. Вы можете изучить
AdapterView
,ListView
иAdapter
класс переноса (некоторый внутренний классListView
IIRC, хотя прошло некоторое время с тех пор, как я изучал это поведение).