やりたいこと
Fragment上にメニューを配置、および押されたときの動作を実装したい。
手順
menuを作成する
表示したいmenuをXMLファイルで作成しましょう。
各メニューはitemタグで表します。
ここでは例として、削除アイコン・編集アイコン・送信アイコンを表示してみましょう。
<?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/menu_delete" android:icon="@drawable/ic_delete" android:title="削除" app:showAsAction="always" /> <item android:id="@+id/menu_edit" android:icon="@drawable/ic_edit" android:title="編集" app:showAsAction="always" /> <item android:id="@+id/menu_send" android:icon="@drawable/ic_send" android:title="送信" app:showAsAction="always" /> </menu>
メニューのXMLファイルはres>menuに作成します。
menuディレクトリがなければ、resを右クリックし、New>Android Resource Directoryでディレクトリを作成しよう。
setHasOptionsMenu(true)を呼ぶ
Activityと異なり、FragmentでMenuを表示する場合にはsetHasOptionsMenuメソッドを呼ぶ必要があります。
引数にtrueを渡すと表示されるようになりますよ。
例として、onCreateの中で実行しています。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) }
忘れがちなので気をつけて。setHasOptionsMenu(true)が実行されないとonCreateOptionsMenu(後述)が呼ばれません。
onCreateOptionsMenuをオーバーライドする
メニューを表示したいFragmentでonCreateOptionsMenuをオーバーライドします。
inflateメソッドの第1引数に、先ほど作成したmenuを渡してあげましょう。
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { inflater?.inflate(R.menu.menu_main_fragment, menu) }
Activityと異なり、Boolean値をreturnする必要はありません。
onOptionsItemSelectedをオーバーライドする
最後にメニューをタップされたときの動作を実装するため、メニューを表示したいFragmentでonOptionsItemSelectedをオーバーライドします。
押されたMenuItemが引数で渡ってくるので、itemIdでどのメニューが押されたか判定しましょう。
ここでは例として、各メニューが押されたらToastを表示するようにしています。
override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item?.itemId) { R.id.menu_delete -> { Toast.makeText(requireContext(), "削除ボタンが押されました", Toast.LENGTH_SHORT).show() return false } R.id.menu_edit -> { Toast.makeText(requireContext(), "編集ボタンが押されました", Toast.LENGTH_SHORT).show() return false } R.id.menu_send -> { Toast.makeText(requireContext(), "送信ボタンが押されました", Toast.LENGTH_SHORT).show() return false } } return true }
まとめ
Fragmentでメニューを表示するには
- menuを作成する
- setHasOptionsMenu(true)を呼ぶ
- onCreateOptionsMenuをオーバーライドして、メニューをセット
- onOptionsItemSelectedをオーバーライドして、メニュー押下時の処理を記述
を行いましょう。
実装は以上です。
ソースコード
MainFragment.kt
package katapiproject.practice import android.os.Bundle import android.support.v4.app.Fragment import android.view.* import android.widget.Toast class MainFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_main, container, false) } override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { inflater?.inflate(R.menu.menu_main_fragment, menu) } override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item?.itemId) { R.id.menu_delete -> { Toast.makeText(requireContext(), "削除ボタンが押されました", Toast.LENGTH_SHORT).show() return false } R.id.menu_edit -> { Toast.makeText(requireContext(), "編集ボタンが押されました", Toast.LENGTH_SHORT).show() return false } R.id.menu_send -> { Toast.makeText(requireContext(), "送信ボタンが押されました", Toast.LENGTH_SHORT).show() return false } } return true } companion object { fun newInstance() = MainFragment() } }
menu_main_fragment.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/menu_delete" android:icon="@drawable/ic_delete" android:title="削除" app:showAsAction="always" /> <item android:id="@+id/menu_edit" android:icon="@drawable/ic_edit" android:title="編集" app:showAsAction="always" /> <item android:id="@+id/menu_send" android:icon="@drawable/ic_send" android:title="送信" app:showAsAction="always" /> </menu>