今回は結構複雑です。

 レイアウトのxmlファイルを作る場合は、Android Studioの機能を作って作った方が楽。この方法はこちら
 今回作成したレイアウトファイルはこのような感じ。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/itm01"
        android:title="Item" />
    <item
        android:id="@+id/itm02"
        android:title="Item" />
    <item
        android:id="@+id/itm03"
        android:title="Item" ></item>
</menu>
 アクションモードを利用する場合は、アクションモードが発生するイベントを受信するクラスを作ることが必要。クラスは別に作ってもいいが、たぶんアクティビティに継承させたほうが楽だと思う。
 具体的にはActionMode.Callbackをインターフェースとして継承したクラスを作る。今回は下記のようにアクティビティクラスに継承させている。
 アクションモードはstartActionModeを実行することで生成される。生成されるとさきほど継承したインターフェースの各メソッドが呼ばれるので、そこで様々な処理をする。
 なおアクションモードのインスタンスが生成されていても何度もボタンを押すなりすれば新しいインスタンスが次々と生成されてしまうので、アクションモードのインスタンスを保持するメンバ変数を作成しておき、nullのときだけは作り、nullでないときはインスタンスを作らないというような処理を記述する必要がある。今回はbuttonのOnLongClickListenerでアクションモードを作るようにし、インスタンスをmActionModeのメンバ変数に格納するようにしている。
 まずonCreateActionModeが生成時に呼ばれるので、そこでアクションモードを生成する。
 onPrepareActionModeは再表示時に呼ばれるメソッドで、そこで何か変更があったときに処理をする。このメソッドはCreateが呼ばれないときでも再表示時には必ず呼ばれるというが、どのタイミングでこのイベントが発生するのかいまいちよくわからない。
 onActionItemClickedはアイテムがクリックされたときに発生するイベントで、ここに様々な処理を記述しておく。例によってitemidにアイテムのidが入っているので、それでitemを区別することができる。
 onDestroyActionModeは終了時に発生するイベント。 


//コールバックさせるため継承させておく class MainActivity : AppCompatActivity(), ActionMode.Callback { //actionModeが出ているときもボタンはクリックできるので重複処理しないために判断する private var mActionMode: ActionMode? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) btnTest.setOnLongClickListener { //mActionModeがnullじゃないときはアクションバーが出ているので何もしない if (mActionMode != null) { Log.v("nullpo","not null") //falseを返すとこのあとにclickイベントも発生する false } else { //mActionModeがnullなときはアクションバーが出ていないので作成する mActionMode = this.startActionMode(this) Log.v("nullpo","null") //trueを返すとこのあとのclickイベントが発生しない true } } }
//startActionで発生するイベント override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { Log.v("nullpo","Create")
//レイアウトファイルを適用させる mode.menuInflater.inflate(R.menu.main, menu) //アクションモードを作るときはtrue 止めるときはfalse return true } //アクションモードのインスタンスが破棄されずに再度呼び出しがあったときに発生 //Createは作る初回だけだが、こちらは再表示されるたびに呼び出される override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { Log.v("nullpo","prepareaction") //trueで再描画 falseで何もしない return false }
//アイテムがクリックされたときに発生するイベント override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { Log.v("nullpo","Clicked")
//item.itemidにUI部品のidが入っているので、どのアイテムがクリックされたかわかる when (item.itemId) { R.id.itm01 -> { Log.v("nullpo","1") //mode.finish()でアクションモードが閉じる=Destroyされる mode.finish() //ここの返値が調べてもよくわからない //たぶんtrueでこの後に発生するイベントがキャンセル //falseでこの後に発生するイベントも発生する return true } R.id.itm02 -> { Log.v("nullpo","2") //mode.finish()しないとアクションモードが出続けるので続けて選択できる return true } R.id.itm03 -> { Log.v("nullpo","3") return true } else -> { return false } } } override fun onDestroyActionMode(mode: ActionMode) { Log.v("nullpo","destroy") //終了したときにはnullを入れておく mActionMode = null } }