Click on EditText's drawable right with Espresso

前端 未结 4 641
小鲜肉
小鲜肉 2021-02-10 00:54

How could be possible to click on EditText\'s right drawable (check the screenshot)? I have tried several ways but I always get stuck.

public static Matcher

        
4条回答
  •  南旧
    南旧 (楼主)
    2021-02-10 01:41

    Perfect answer from @dareniott .

    I just made it in kotlin:

    import android.graphics.Point
    import android.support.annotation.IntDef
    import android.support.test.espresso.UiController
    import android.support.test.espresso.ViewAction
    import android.support.test.espresso.matcher.BoundedMatcher
    import android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom
    import android.view.MotionEvent
    import android.view.View
    import android.widget.TextView
    import org.hamcrest.Description
    import org.hamcrest.Matcher
    import org.hamcrest.Matchers.allOf
    
    class ClickDrawableAction(@param:Location @field:Location private val drawableLocation: Int) : ViewAction {
        override fun getConstraints(): Matcher {
            return allOf(isAssignableFrom(TextView::class.java), object : BoundedMatcher(TextView::class.java) {
                override fun matchesSafely(tv: TextView): Boolean {
                    return tv.requestFocusFromTouch() && tv.compoundDrawables[drawableLocation] != null
                }
    
                override fun describeTo(description: Description) {
                    description.appendText(DESCRIPTION_HAS_DRAWABLE)
                }
            })
        }
    
        override fun getDescription(): String {
            return DESCRIPTION_CLICK_DRAWABLE
        }
    
        override fun perform(uiController: UiController, view: View) {
            val tv = view as TextView
            if (tv.requestFocusFromTouch())
            {
                val drawableBounds = tv.compoundDrawables[drawableLocation].bounds
                val clickPoint = arrayOfNulls(SIZE_CLICK_POINT)
                clickPoint[LEFT] = Point(tv.left + drawableBounds.width() / HALF_DIVISOR, (tv.pivotY + drawableBounds.height() / HALF_DIVISOR).toInt())
                clickPoint[TOP] = Point((tv.pivotX + drawableBounds.width() / HALF_DIVISOR).toInt(), tv.top + drawableBounds.height() / HALF_DIVISOR)
                clickPoint[RIGHT] = Point(tv.right + drawableBounds.width() / HALF_DIVISOR, (tv.pivotY + drawableBounds.height() / HALF_DIVISOR).toInt())
                clickPoint[BOTTOM] = Point((tv.pivotX + drawableBounds.width() / HALF_DIVISOR).toInt(), tv.bottom + drawableBounds.height() / HALF_DIVISOR)
                clickPoint[drawableLocation]?.let { point ->
                    if (tv.dispatchTouchEvent(
                                    MotionEvent.obtain(
                                            android.os.SystemClock.uptimeMillis(),
                                            android.os.SystemClock.uptimeMillis(),
                                            MotionEvent.ACTION_DOWN,
                                            point.x.toFloat(),
                                            point.y.toFloat(),
                                            0)
                            )) {
                        tv.dispatchTouchEvent(
                                MotionEvent.obtain(
                                        android.os.SystemClock.uptimeMillis(),
                                        android.os.SystemClock.uptimeMillis(),
                                        MotionEvent.ACTION_UP,
                                        point.x.toFloat(),
                                        point.y.toFloat(),
                                        0))
                    }
                }
    
            }
        }
    
        @IntDef(LEFT, TOP, RIGHT, BOTTOM)
        @Retention(AnnotationRetention.SOURCE)
        annotation class Location
    
        companion object {
            const val LEFT = 0
            const val TOP = 1
            const val RIGHT = 2
            const val BOTTOM = 3
            const val SIZE_CLICK_POINT = 4
            const val HALF_DIVISOR = 2
            const val DESCRIPTION_HAS_DRAWABLE = "has drawable"
            const val DESCRIPTION_CLICK_DRAWABLE = "click drawable "
        }
    }
    

提交回复
热议问题