检测哪个select的项目(在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; } }); } }); 

但只是挂起,直到ANRpopup。 我怀疑菜单创build后,不再selectListItem

看起来您可以监控点击或长时间点击,然后在那里logging点击的项目:

  mArrivalsList.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) { // record position/id/whatever here return false; } }); 

但是这对我来说感觉非常糟糕。 有没有人有更好的解决scheme呢?

我正是这样做的。 在我的onCreateContextMenu(...)方法中,我将ContextMenu.ContextMenuInfoAdapterView.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); } 

请注意,我将所选文本以及select标识存储在专用字段中。 由于UI是线程限制的,我知道selectedWord和selectedWordId字段对于以后的操作是正确的。

首先,我想知道是否使用View.setOnCreateContextMenuListener()使事情变得复杂一点。 如果你使用Activity.registerForContextMenu() ,事情变得更容易,因为你可以使用Activity.onCreateContextMenu()Activity.onContextItemSelected()来处理所有的菜单事件。 它基本上意味着你不必定义所有这些匿名内部类来处理每一个事件; 你只需要重写一些Activity方法来处理这些上下文菜单事件。

其次,肯定有更简单的方法来检索当前select的项目。 所有你需要做的就是保持对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); } 

这是如何创build上下文菜单的另一种方式如何删除这里select的项目是整个代码

  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; } 

不是视图参数实际选定的行视图,还是我在这里错过了问题?

 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 }