У меня есть ListView, который позволит пользователю длинному нажатию объект для получения контекстного меню. Проблема, которую я имею, находится в определении который ListItem
они долго нажатый. Я попытался делать это:
myListView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override public void onCreateContextMenu(ContextMenu menu, final View v, ContextMenuInfo menuInfo) {
menu.add("Make Toast")
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override public boolean onMenuItemClick(MenuItem item) {
String toastText = "You clicked position " + ((ListView)v).getSelectedItemPosition();
Toast.makeText(DisplayScheduleActivity.this, toastText, Toast.LENGTH_SHORT).show();
return true;
}
});
}
});
но это просто зависает, пока ANR не открывается. Я подозреваю, что после меню создается ListItem
больше не выбирается.
Похоже, что Вы могли контролировать для щелчков, или длинные щелчки тогда записывают нажатый объект там:
mArrivalsList.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override public boolean onItemLongClick(AdapterView> parent, View v, int position, long id) {
// record position/id/whatever here
return false;
}
});
но это чувствует абсолютно kludgey мне. У кого-либо есть какие-либо лучшие решения для этого?
Я делаю именно это. В моем методе onCreateContextMenu (...)
я привел ContextMenu.ContextMenuInfo
к AdapterView.AdapterContextMenuInfo
. Оттуда вы можете получить targetView, который снова передадите виджету. Полный код доступен в HomeActivity.java , ищите метод onCreateContextMenu (...)
.
@Override
public void onCreateContextMenu(ContextMenu contextMenu,
View v,
ContextMenu.ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) menuInfo;
selectedWord = ((TextView) info.targetView).getText().toString();
selectedWordId = info.id;
contextMenu.setHeaderTitle(selectedWord);
contextMenu.add(0, CONTEXT_MENU_EDIT_ITEM, 0, R.string.edit);
contextMenu.add(0, CONTEXT_MENU_DELETE_ITEM, 1, R.string.delete);
}
Обратите внимание, что я сохраняю выделенный текст, а также идентификатор выбора в частных полях. Поскольку пользовательский интерфейс ограничен потоком, я знаю, что поля selectedWord и selectedWordId будут правильными для последующих действий.
Прежде всего, мне интересно, не слишком ли вы усложняете ситуацию, используя View.setOnCreateContextMenuListener ()
. Все станет намного проще, если вы используете Activity.registerForContextMenu ()
, потому что тогда вы можете просто использовать Activity.onCreateContextMenu ()
и Activity.onContextItemSelected ()
, чтобы обрабатывать все события вашего меню. По сути, это означает, что вам не нужно определять все эти анонимные внутренние классы для обработки каждого события; вам просто нужно переопределить несколько методов Activity для обработки этих событий контекстного меню.
Во-вторых, определенно есть более простые способы получить текущий выбранный элемент. Все, что вам нужно сделать, это сохранить ссылку либо на ListView
, либо на адаптер
, используемый для его заполнения. Вы можете использовать ContextMenuInfo как AdapterContextMenuInfo, чтобы получить позицию элемента; а затем вы можете использовать ListView.getItemAtPosition ()
или Adapter.getItem ()
, чтобы получить объект
, специально связанный с тем, что было щелкнуто. Например, предположим, что я использую Activity.onCreateContextMenu ()
, я мог бы сделать это:
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// Get the info on which item was selected
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
// Get the Adapter behind your ListView (this assumes you're using
// a ListActivity; if you're not, you'll have to store the Adapter yourself
// in some way that can be accessed here.)
Adapter adapter = getListAdapter();
// Retrieve the item that was clicked on
Object item = adapter.getItem(info.position);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// Here's how you can get the correct item in onContextItemSelected()
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
Object item = getListAdapter().getItem(info.position);
}
Мы успешно использовали:
@Override
public boolean onContextItemSelected
(
MenuItem item
)
{
if (!AdapterView.AdapterContextMenuInfo.class.isInstance (item.getMenuInfo ()))
return false;
AdapterView.AdapterContextMenuInfo cmi =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo ();
Object o = getListView ().getItemAtPosition (cmi.position);
return true;
}
Разве аргумент view не является фактическим видом выбранной строки, или я не понял вопроса?
ListView lv;
private OnItemLongClickListener onLongClick = new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
lv.showContextMenuForChild(arg1);
lv.showContextMenu();
return false;
}
};