AndroidStudio アクションバー オーバーフローメニュー

アクションバーへオーバーフローメニューを表示させ
その中のアイテムを押した時の処理をつくる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/56aa2690-82c3-4251-8c9a-90ea8e4ef4ba.png)

:::note info
## イメージ
選択した種類の商品へ切り替わる
![携帯.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/99936dec-aae6-f1a5-5a7d-e9931305ffb4.gif)
:::
## アクションバーの設定確認
:::note warn
**※アクションバーが表示されない時に確認**
:::

app > values > themes > themes.xmlを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/363eb2d7-d80f-9934-5923-61c5f071561a.png)

~~~xml:themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Base.Theme.CustomLayout" parent="Theme.Material3.DayNight.NoActionBar">
        <!-- Customize your light theme here. -->
        <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
    </style>

    <style name="Theme.CustomLayout" parent="Base.Theme.CustomLayout" />
</resources>
~~~

:::note info
**<<foo>style name="Base.Theme.CustomLayout" parent="Theme.Material3.DayNight.NoActionBar">**
この状態の時はアクションバーが表示されない

なのでこれの
**.NoActionBar**の部分を消す

消去後↓
**<<foo>style name="Base.Theme.CustomLayout" parent="Theme.Material3.DayNight>**
こうすると表示される
:::


## リソースファイルの作成
オーバーフローメニュー用のリソースファイルを作成する
<br>

### リソース用の新規フォルダーの作成
ファイル > 新規 > Android Resource Directoryを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/45ceff5a-50fc-957b-efb3-f5cbe2ff4bd0.png)

**ウィザードの設定**
Directory name : 好きな名前を付ける
Resource type : menu を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/1c88949a-6356-da1e-d25f-7e10d695b1eb.png)

設定が完了したらOKを押す。するとフォルダが作成される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/5f59ff3d-0135-d470-3903-56a48a0b0764.png)

### 作成したフォルダー内へxmlファイルを作成
menuの所で右クリック > 新規 > menu Resource Fileを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/e30a0414-ee97-3397-08df-8afc581e7806.png)

### 作成したxmlへ記述
今回は２つitemを設定
~~~xml:さっき作成したxmlファイル
<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menuListOptionfruit"
        app:showAsAction="never"
        android:title="くだもの" />
    <item
        android:id="@+id/menuListOptionvegetable"
        app:showAsAction="never"
        android:title="やさい"/>
</menu>
~~~
:::note info
### タグ
- **<<foo>menu><<foo>/menu>と<<foo>item>**
<<foo>item>タグを<<foo>menu><<foo>/menu>で囲う
### menuに必要な属性
- **xmlns:android**
いつもの="http://<foo>schemas.android.com/apk/res/android"
- **xmlns:app(任意)**
今回はapp:showAsAction属性などをサポートするために追加
### itemに必要な属性
- **android:id**
アイテムを識別するためのID
android:id="@+id/任意のidを設定"


- **android:title**
メニューアイテムの表示テキスト
android:title="任意の文字列"

- **android:showAsAction**
メニューアイテムの表示方法
この属性が重要で、今回の場合は"never"を設定
android:showAsAction="never"
:::

## オーバーフローメニューを表示させる
### 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 boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_options_menu_list, menu);
        return true;
    }
    //＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋
}
~~~
:::note info
解説
---
- **public boolean onCreateOptionsMenu(Menu menu){}**
必ず@<foo>Overrideする
オプションメニューを初期化するために呼び出されるメソッドでアクティビティが最初に作成された際、一度だけ呼び出される
- **MenuInflater inflater = getMenuInflater();**
MenuInflaterオブジェクトを取得
- **inflater.inflate(R.menu.menu_options_menu_list, menu);**
  - 引数
第１
R.menu.上で作ったxmlファイル名を指定
※menuの部分はフォルダー作成時のフォルダ名のこと
第２
menuは引数の変数名
- **return true;**
メソッドがboolean型なのでtrueかfalseを返す必要がある
trueを返すことで、Androidはメニューを表示する
:::
これでオーバーフローメニューがでて
それを押すことでxmlのitemに設定したものが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/8ded4b19-ed37-9520-20f1-4d644deec635.png)

## オーバーフローメニューを押した時の処理
### MaineActivityへ追記する
~~~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 boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_options_menu_list, menu);
        return true;
    }
    //追加＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if(itemId == R.id.menuListOptionfruit) {
            //ここに処理を記入
        } else if (itemId == R.id.menuListOptionvegetable) {
            //ここに処理を記入
        }else{
            returnVal = super.onOptionsItemSelected(item);
        }
    }
    //＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋＋
}
~~~

:::note info
**解説**
---
- **public boolean onOptionsItemSelected(MenuItem item){}**
オーバーフローメニューの中のアイテムを押した時に
その押したアイテムをidで分岐させて各処理を行わせる


~~~java
int itemId = item.getItemId();
if(itemId == R.id.menuListOptionfruit) {
    //くだものを押した時の処理を記入
    return true;
} else if (itemId == R.id.menuListOptionvegetable) {
    //やさいを押した時の処理を記入
    return true;
}else{
    return super.onOptionsItemSelected(item);
}
~~~
if文でidを識別して処理を行う
今回の場合商品リストを変更する処理を入れるとよい
必ずreturnすること基本的にtrueを返す

swich文は定数式を入れてくださいとエラーがでる
これはバージョンによって違うと思われる

**return super.onOptionsItemSelected(item);**
エラー回避とデフォルトの動作を維持し、
期待される動作を確実に実現するために必ず分岐させる
:::