Обнаружение того, какой выбранный элемент (в ListView) породил ContextMenu (Android)
у меня есть 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;
}
});
}
});
но он просто висит до АНР всплывает. Я подозреваю, что после создания меню 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 для меня. У кого-нибудь есть лучшие решения для этого?
8 ответов:
я делаю именно это. В моем
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()для обработки всех событий меню. Это в основном означает, что вам не нужно определять все эти анонимные внутренние классы для обработки каждого события; вам просто нужно переопределить несколько методов активности для обработки этих событий контекстного меню.во-вторых, есть определенно более простые способы извлечение текущего выбранного элемента. Все, что вам нужно сделать, это сохранить ссылку на
ListViewилиAdapterиспользуется для его заполнения. Вы можете использовать ContextMenuInfo в качестве AdapterContextMenuInfo для получения позиции элемента; а затем вы можете использоватьListView.getItemAtPosition()илиAdapter.getItem()для полученияObjectспециально связан с тем, что было нажато. Например, предположим, что я использую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); }
это еще один способ о том, как создать контекстное меню N как удалить элемент, выбранный здесь весь код
public class SimpleJokeList extends Activity { public static final int Upload = Menu.FIRST + 1; public static final int Delete = Menu.FIRST + 2; int position; ListView lv; EditText jokeBox; Button addJoke; MyAdapter adapter; private ArrayAdapter<String> mAdapter; private ArrayList<String> mStrings = new ArrayList<String>(); String jokesToBeAdded; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simplejokeui); lv=(ListView)findViewById(R.id.jokelist); addJoke=(Button)findViewById(R.id.addjoke); jokeBox=(EditText)findViewById(R.id.jokebox); mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings); registerForContextMenu(lv); listItemClicked(); addJokes(); private void addJokes() { // TODO Auto-generated method stub addJoke.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub jokesToBeAdded=jokeBox.getText().toString(); if(jokesToBeAdded.equals("")){ Toast.makeText(getApplicationContext(), "please enter some joke", Toast.LENGTH_LONG).show(); } else{ lv.setAdapter(mAdapter); mAdapter.add(jokesToBeAdded); jokeBox.setText(null); } } }); } private void listItemClicked() { // TODO Auto-generated method stub lv.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub position=arg2; return false; } }); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // TODO Auto-generated method stub super.onCreateContextMenu(menu, v, menuInfo); populateMenu(menu); menu.setHeaderTitle("Select what you wanna do"); } private void populateMenu(ContextMenu menu) { // TODO Auto-generated method stub menu.add(Menu.NONE, Upload, Menu.NONE, "UPLOAD"); menu.add(Menu.NONE, Delete, Menu.NONE, "DELETE"); } @Override public boolean onContextItemSelected(MenuItem item) { return (applyMenuChoice(item) || super.onContextItemSelected(item)); } private boolean applyMenuChoice(MenuItem item) { // TODO Auto-generated method stub switch (item.getItemId()) { case Delete: String s=mAdapter.getItem(position); mAdapter.remove(s); // position--; Toast.makeText(getApplicationContext(),"Congrats u HAve Deleted IT", Toast.LENGTH_LONG).show(); return (true); } return false; }
и не забудьте поставить этот
registerForContextMenu(listview);в своем
onCreateметод, чтобы получить ваше контекстное меню видимым.
мы использовали с успехом:
@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; } };
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; View TargetV=(View) info.targetView; text1 = (String) ((TextView) TargetV.findViewById(R.id.textView1)).getText(); text2 = (String) ((TextView) TargetV.findViewById(R.id.textView2)).getText(); if(List3Ok){ text3 = (String) ((TextView) TargetV.findViewById(R.id.textView3)).getText(); } selectedWord = text1 + "\n" + text2 + "\n" + text3; selectedWordId = info.id; menu.setHeaderTitle(selectedWord); MenuInflater inflater = this.getActivity().getMenuInflater(); inflater.inflate(R.menu.list_menu, menu); }
Я случай, когда вы используете
SimpleCursorAdapderвы можете сделать это@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { getActivity().getMenuInflater().inflate(R.menu.project_list_item_context, menu); // Getting long-pressed item position AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; int position = info.position; // Get all records from adapter Cursor c = ((SimpleCursorAdapter)getListAdapter()).getCursor(); // Go to required position c.moveToPosition(position); // Read database fields values associated with our long-pressed item Log.d(TAG, "Long-pressed-item with position: " + c.getPosition()); Log.d(TAG, "Long-pressed-item _id: " + c.getString(0)); Log.d(TAG, "Long-pressed-item Name: " + c.getString(1)); Log.d(TAG, "Long-pressed-item Date: " + c.getString(2)); Log.d(TAG, "Long-pressed-item Path: " + c.getString(3)); // Do whatever you need here with received values }
Comments