특정 view 에서 key event 를 받기 위해 dispatchKeyEvent 를 사용하려고 했는데요,
그런데 예상과 달리 dispatchKeyEvent 가 호출이 안 되는 문제가 있었어요.
1. 원인
호출이 안된 이유는 Focus 문제였습니다..ㅠㅠ
Android Developer: dispatchKeyEvent
문서에서 확인된 내용으로 dispatchKeyEvent 가 호출되기 위해서
"if this view has focus, if will dispatch to itself "
해당 View 가 Focus 를 가져야 한다고 하네요.
2. 해결 방법
dispatchKeyEvent 가 호출되야하는 View 에 Focus 를 줘야하는데
requestChildFocus 를 사용해서 해결할 수 있었습니다.
(혹시 또 다른 방법이 있다면 댓글 남겨주세요..!)
Android Developer: requestChildFocus
3. 예제
키 이벤트를 받는 뷰(KeyEventView) 를 추가하여,
뒤로가기 버튼으로 dispatchKeyEvnet 메소드가 잘 호출되는지 확인하였습니다.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val keyEventView = KeyEventView(this) // keyEventView
binding.btnAddView.setOnClickListener {
if (!binding.lyContainer.contains(keyEventView)) {
keyEventView.requestChildFocus() // keyEventView Focus
binding.lyContainer.addView(keyEventView)
}
}
binding.btnRemoveView.setOnClickListener {
if (binding.lyContainer.contains(keyEventView)) {
binding.lyContainer.removeView(keyEventView)
}
}
}
}
KeyEventView.kt
class KeyEventView(context: Context?) : LinearLayout(context) {
private var binding: KeyEventViewBinding
init {
binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.key_event_view, this, true)
}
fun requestChildFocus() {
// KeyEvent View Focus
requestChildFocus(binding.root, null)
}
override fun requestChildFocus(child: View?, focused: View?) {
super.requestChildFocus(child, focused)
}
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
val action = event?.action
val keyCode = event?.keyCode
event?.let {
val result = "keyCode $keyCode, action $action"
binding.tvKeyEvent.text = result
return true
}
return super.dispatchKeyEvent(event)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btnAddView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add View"
android:textAllCaps="false" />
<Button
android:id="@+id/btnRemoveView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Remove View"
android:textAllCaps="false" />
<FrameLayout
android:id="@+id/lyContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</FrameLayout>
</LinearLayout>
</layout>
key_event_view.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#A0A0AA"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tvTestView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="KeyEventView"
android:textColor="@color/black"
android:textSize="30dp" />
<TextView
android:id="@+id/tvKeyEvent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="30dp" />
</LinearLayout>
</layout>
0 comments: