AndroidStudio コンテキストメニュー

## 長押しでコンテキストメニューを出す
:::note info
## イメージ
リストのアイテム長押しでコンテキストメニューを出す
![携帯.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/9aa1c2a3-77ff-a48a-2e36-55a47dae94ab.gif)
:::

※リストビューは各自好きに作る

## コンテキストメニュー用のカスタマイズ
カスタム用のxmlファイルを用意する
参考 ⇒ [リソースファイルの作成](https://qiita.com/mk-000856/items/43a96f7faf85ca743000#%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90)

カスタム用のxmlファイルを用意したら記述する
~~~xml:カスタム用のxml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/好きなid"
        android:title="@string/表示されるテキスト"/>
    <!--itemは必要なだけ作る-->
</menu>
~~~

## MainActivityへ記述する
リストを長押しした時にコンテキストメニューを出す用
~~~java: MaineActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
    }
//追記＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋
    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo){
        super.onCreateContextMenu(menu, view, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_context_nemu_list, menu);
        menu.setHeaderTitle(R.string.menu_list_context_header);
    }
//＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋
~~~
:::note info
解説
---
**onCreateContextMenu**メソッド
コンテキストメニューを生成するために呼び出される
**引数**
- **ContextMenu** menu
作成されるコンテキストメニューのオブジェクト
このオブジェクトにメニュー項目を追加
- **View** view
長押しされたビューを示す
- **ContextMenu.ContextMenuInfo** menuInfo
追加の情報が含まれており
特定のビュー（例えば、ListView）で使用

**super.onCreateContextMenu(menu, view, menuInfo);**
これは書いておく必要があると思っとくとよい
「親クラスの動作を破棄しない」という安全策

**MenuInflater inflater = getMenuInflater();**
オブジェクトの取得

**inflater.inflate(R.menu.xmlのファイル名, menu);**
res/menuの中に作ったカスタムxmlファイルを指定する
指定したものをmenuオブジェクトへ展開する
:::
これで長押しするとコンテキストメニューが出てくるようになる

## メニュー内のアイテムを押した時の処理を作る
今回はトーストを出すようにする
### MainActivityへ追加
~~~java
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
        int listPosition = info.position;
        Map<String, Object> menu = menuList.get(listPosition);
        int itemId = item.getItemId();
        
        if(itemId == R.id.menuListContextDesc) {
            String desc = (String) menu.get("desc");
            Toast.makeText(this, desc, Toast.LENGTH_SHORT).show();
        }else{
            return super.onContextItemSelected(item);
        }
        return true;
    }
~~~
:::note info
解説
---
**AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();**
長押しされたアイテムの情報(positionとか)を取得するために使う

**int listPosition = info.position;**
長押しされたリストアイテムの位置（インデックス）を取得

**Map<String, Object> menu = menuList.get(listPosition);**
リストをどのように管理しているかで変わる
場合によってはこの記述は必要ない
参考 ⇒ [Mapについて](https://qiita.com/mk-000856/items/b3d9b0e1f8574c1a82c6#map%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

**int itemId = item.getItemId();**
選択されたコンテキストメニューのIDを取得

**if文**
取得したidで分岐させる
switch文は定数式を入れる必要がありエラーが出てしまう

**String desc = (String) menu.get("desc");
Toast.makeText(this, desc, Toast.LENGTH_SHORT).show();**
Mapには"desc"というキーで説明文を入れており
この説明文を引き出し、トーストに表示させる

**return super.onContextItemSelected(item);**
選択されたメニュー項目が特定の処理に該当しなかった場合、
親クラスのonContextItemSelectedメソッドに処理を委譲

**return true;**
処理が正常に完了したことを示す
基本的にtrueを返すようにする
:::

これでコンテキストメニューのアイテムを選択した時
何かしらの処理ができるようになった