web-dev-qa-db-ja.com

どの選択項目(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;
     }
    });
  } 
 });

ただし、 [〜#〜] 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;
  }
 });

しかし、それは私にとって非常に厄介です。誰もこれに対してより良い解決策がありますか?

56
Jeremy Logan

私はまさにこれを行います。 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);
}
_

選択したテキストと選択IDをプライベートフィールドに保存することに注意してください。 UIはスレッドに限定されているため、selectedWordフィールドとselectedWordIdフィールドは、後のアクションで正しくなることを知っています。

75
Eric Burke

まず、View.setOnCreateContextMenuListener()を使用して、少し複雑になりすぎているのではないかと思っています。 Activity.registerForContextMenu()を使用すると、すべてのメニューイベントを処理するためにActivity.onCreateContextMenu()Activity.onContextItemSelected()を使用できるため、物事がはるかに簡単になります。基本的に、すべてのイベントを処理するためにこれらすべての匿名内部クラスを定義する必要はありません。これらのコンテキストメニューイベントを処理するには、いくつかのActivityメソッドをオーバーライドするだけです。

第二に、現在選択されているアイテムを取得する簡単な方法が間違いなくあります。必要なことは、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);
}
66
Daniel Lew

これは、コンテキストメニューを作成する方法の別の方法です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;
}
4
Ali Ashraf

そしてこれを置くことを忘れないでください

registerForContextMenu(listview);

onCreateメソッドで、コンテキストメニューを表示します。

3
sami boussacsou

ビュー引数は、実際に選択された行のビューではありませんか、またはここで質問がありませんか?

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;
    }
};
2
Patrick Kafka

私たちは成功して使用しました:

@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;
    }
2
Nate
@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);
}
1
Omid Omidi

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

}
0
Andrey Bulanov