Reputation: 4080
I am trying to get view in dispatchTouchEvent()
.
However, this only passes MotionEvent. It has x and y position. But, it doesn't pass view itself.
I can get view with currentFocus
. However, this gets view after having a focus. And when you touch EditText and then Outside of EdiText, EditText still has the focus. So, currentFocus
will be the same EditText.
What I am trying to do is closing keyboard when I touch non-EditText. And showing keybaord when I touch EditText. But when I touch EditText A and then EditText B, it shouldn't be blinking(hiding and showing again)
What I was trying is:
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
var view = currentFocus
if (view == null) {
view = View(this@BaseActivity)
}
ev?.let {
val isInRange = isRegionOfInterest(view, ev)
if(!isInRange){
hideKeyboard()
currentFocus?.clearFocus()
}
}
return super.dispatchTouchEvent(ev)
}
But this doesn't seem to be the right way. It'd be great if I can get a view with X and Y positon. Do you know any way to do that?
Upvotes: 0
Views: 270
Reputation: 4080
This is what I did:
private fun isHidableArea(x: Float?, y: Float?): Boolean {
var result = true
if (x == null || y == null) return result
val rootView = (findViewById<View>(R.id.content) as ViewGroup).getChildAt(0) as ViewGroup
val interestViewList = rootView.findInterestViewListByPosition(x, y)
loop@ for (v in interestViewList) {
if (v is EditText) {
result = false
break@loop
}
}
return result
}
private fun View.findInterestViewListByPosition(x: Float, y: Float): ArrayList<View> {
val childViewList = this.getAllChildren()
val interestViewList = ArrayList<View>()
for (it in childViewList) {
if (isRegionOfInterest(it, x, y)) {
interestViewList.add(it)
}
}
return interestViewList
}
private fun View.getAllChildren(): List<View> {
val result = ArrayList<View>()
if (this !is ViewGroup) {
result.add(this)
} else {
for (index in 0 until this.childCount) {
val child = this.getChildAt(index)
result.addAll(child.getAllChildren())
}
}
return result
}
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
if (isHidableArea(ev.x, ev.y)) {
hideKeyboard()
}
return super.dispatchTouchEvent(ev)
}
private fun isRegionOfInterest(view: View, x: Float, y: Float): Boolean {
return x in view.x - 0..(view.x + view.width) && y in view.y - 0..view.y + view.height
}
This gets all the child view and compare the position.
Upvotes: 0