今回は結構複雑です。
レイアウトのxmlファイルを作る場合は、Android Studioの機能を作って作った方が楽。この方法はこちら。
今回作成したレイアウトファイルはこのような感じ。
具体的にはActionMode.Callbackをインターフェースとして継承したクラスを作る。今回は下記のようにアクティビティクラスに継承させている。
アクションモードはstartActionModeを実行することで生成される。生成されるとさきほど継承したインターフェースの各メソッドが呼ばれるので、そこで様々な処理をする。
なおアクションモードのインスタンスが生成されていても何度もボタンを押すなりすれば新しいインスタンスが次々と生成されてしまうので、アクションモードのインスタンスを保持するメンバ変数を作成しておき、nullのときだけは作り、nullでないときはインスタンスを作らないというような処理を記述する必要がある。今回はbuttonのOnLongClickListenerでアクションモードを作るようにし、インスタンスをmActionModeのメンバ変数に格納するようにしている。
まずonCreateActionModeが生成時に呼ばれるので、そこでアクションモードを生成する。
onPrepareActionModeは再表示時に呼ばれるメソッドで、そこで何か変更があったときに処理をする。このメソッドはCreateが呼ばれないときでも再表示時には必ず呼ばれるというが、どのタイミングでこのイベントが発生するのかいまいちよくわからない。
onActionItemClickedはアイテムがクリックされたときに発生するイベントで、ここに様々な処理を記述しておく。例によってitemidにアイテムのidが入っているので、それでitemを区別することができる。
onDestroyActionModeは終了時に発生するイベント。
レイアウトの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
}
}