はじめに
私の開発しているアプリKUMIWAKEでは、フォームの入力画面で任意の場所をダブルタップすると、一番上のフォームに入力ができるような機能を実装しています。なぜこの機能を実装したかというと、最近のケータイは画面が大きすぎて上のフォームまで指が余裕で届かないからですね。
今回はこのような画面のタッチイベント取得についてまとめてみました。
タッチイベントの実装
まず、タッチイベントを拾いたい画面のアクティビティの記述です。
MyGestureListener
はジェスチャリスナーを継承したクラスです。後述します。
private lateinit var detector: GestureDetectorCompat
override fun onCreate(savedInstanceState: Bundle?) {
:
//GestureDetectorの初期化とダブルタップリスナの登録
detector = GestureDetectorCompat(this, MyGestureListener())
detector.setOnDoubleTapListener(MyGestureListener())
}
override fun onTouchEvent(event: MotionEvent): Boolean {
mDetector.onTouchEvent(event)
return super.onTouchEvent(event)
}
なお、タッチの領域がスクロールビューの場合は、onTouchEvent
ではタッチイベントがスクロールビューに吸収されてしまうため、こちらを使います。
//スクロールビューの場合こっち呼ぶ
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
super.dispatchTouchEvent(event)
mDetector.onTouchEvent(event)
return super.onTouchEvent(event)
}
MyGestureListener
はこんな感じ。
class MyGestureListener() : GestureDetector.SimpleOnGestureListener() {
//ダブルタップイベント
override fun onDoubleTap(event: MotionEvent): Boolean {
//処理あれこれ
return true
}
}
サンプルコード
はじめに示した「片手で入力機能」の実装を例として示しておきます。
class InputForms : AppCompatActivity() {
private lateinit var detector: GestureDetectorCompat
override fun onCreate(savedInstanceState: Bundle?) {
:
//ダブルタップでフォーカスするEditText
val et = findViewById<EditText>(R.id.input_form)
//キーボード表示のためのマネージャ取得
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
//GestureDetectorの初期化とダブルタップリスナの登録
detector = GestureDetectorCompat(this, MyGestureListener(imm, et))
detector.setOnDoubleTapListener(MyGestureListener(imm, et))
//トースト表示
Toast.makeText(this, "画面をダブルタップで入力を開始", Toast.LENGTH_SHORT).show()
}
override fun onTouchEvent(event: MotionEvent): Boolean {
mDetector.onTouchEvent(event)
return super.onTouchEvent(event)
}
}
class MyGestureListener(private val imm: InputMethodManager, val et: EditText) : GestureDetector.SimpleOnGestureListener() {
//ダブルタップイベント
override fun onDoubleTap(event: MotionEvent): Boolean {
//EditTetにフォーカスを当てる
et.requestFocus()
//ソフトキーボードを表示
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_NOT_ALWAYS)
return true
}
}
最後に
今回はダブルタップイベントを例に挙げましたが、MyGestureListener
ではSimpleOnGestureListener()
を継承しているので、以下を参考に長押しやシングルタップなどの好きなタッチイベントをハンドルできます。
https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener#public-methods
なお、一つの動作でも複数のイベントが発生しますのでどのイベントをハンドルすればよいかは考慮してください。以下のサイトなどが参考になります。
https://dixq.net/Android/02_04.html