使用Espresso单击EditText的可绘制对象 [英] Click on EditText's drawable right with Espresso

查看:63
本文介绍了使用Espresso单击EditText的可绘制对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何单击EditText的右侧可绘制对象(检查屏幕截图)?我尝试了几种方法,但总是会卡住.

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<View> withEditTextDrawable(final int resourceId) {
    return new BoundedMatcher<View, EditText>(EditText.class) {
        @Override
        protected boolean matchesSafely(final EditText editText) {
            // ????

            return false;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("with drawable from resource id: ");
            description.appendValue(resourceId);
        }
    };
}

推荐答案

必须开发此自定义操作和匹配器,以测试某些文本字段右侧的废弃可绘制对象, 这将在Espresso测试中单击TextView的任何可绘制对象(左,上,右,下).

Had to develop this custom action and matcher to test our discard drawables on the right of some text fields, this will click any drawable (left, top, right, bottom) of a TextView in an Espresso test.

用法:

onView(withId(id)).perform(clickDrawables());

方法:

public static ViewAction clickDrawables()
{
    return new ViewAction()
    {
        @Override
        public Matcher<View> getConstraints()//must be a textview with drawables to do perform
        {
            return allOf(isAssignableFrom(TextView.class), new BoundedMatcher<View, TextView>(TextView.class)
            {
                @Override
                protected boolean matchesSafely(final TextView tv)
                {
                    if(tv.requestFocusFromTouch())//get fpocus so drawables become visible
                        for(Drawable d : tv.getCompoundDrawables())//if the textview has drawables then return a match
                            if(d != null)
                                return true;

                    return false;
                }

                @Override
                public void describeTo(Description description)
                {
                    description.appendText("has drawable");
                }
            });
        }

        @Override
        public String getDescription()
        {
            return "click drawables";
        }

        @Override
        public void perform(final UiController uiController, final View view)
        {
            TextView tv = (TextView)view;
            if(tv != null && tv.requestFocusFromTouch())//get focus so drawables are visible
            {
                Drawable[] drawables = tv.getCompoundDrawables();

                Rect tvLocation = new Rect();
                tv.getHitRect(tvLocation);

                Point[] tvBounds = new Point[4];//find textview bound locations
                tvBounds[0] = new Point(tvLocation.left, tvLocation.centerY());
                tvBounds[1] = new Point(tvLocation.centerX(), tvLocation.top);
                tvBounds[2] = new Point(tvLocation.right, tvLocation.centerY());
                tvBounds[3] = new Point(tvLocation.centerX(), tvLocation.bottom);

                for(int location = 0; location < 4; location++)
                    if(drawables[location] != null)
                    {
                        Rect bounds = drawables[location].getBounds();
                        tvBounds[location].offset(bounds.width() / 2, bounds.height() / 2);//get drawable click location for left, top, right, bottom
                        if(tv.dispatchTouchEvent(MotionEvent.obtain(android.os.SystemClock.uptimeMillis(), android.os.SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, tvBounds[location].x, tvBounds[location].y, 0)))
                            tv.dispatchTouchEvent(MotionEvent.obtain(android.os.SystemClock.uptimeMillis(), android.os.SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, tvBounds[location].x, tvBounds[location].y, 0));
                    }
            }
        }
    };
}



这是我为选择要点击的特定可绘制对象所做的改进:



This is a refinement I made to select a specific drawable to click:

用法:

onView(withId(id)).perform(new ClickDrawableAction(ClickDrawableAction.Right));

方法:

public static class ClickDrawableAction implements ViewAction
{
    public static final int Left = 0;
    public static final int Top = 1;
    public static final int Right = 2;
    public static final int Bottom = 3;

    @Location
    private final int drawableLocation;

    public ClickDrawableAction(@Location int drawableLocation)
    {
        this.drawableLocation = drawableLocation;
    }

    @Override
    public Matcher<View> getConstraints()
    {
        return allOf(isAssignableFrom(TextView.class), new BoundedMatcher<View, TextView>(TextView.class)
        {
            @Override
            protected boolean matchesSafely(final TextView tv)
            {
                //get focus so drawables are visible and if the textview has a drawable in the position then return a match
                return tv.requestFocusFromTouch() && tv.getCompoundDrawables()[drawableLocation] != null;

            }

            @Override
            public void describeTo(Description description)
            {
                description.appendText("has drawable");
            }
        });
    }

    @Override
    public String getDescription()
    {
        return "click drawable ";
    }

    @Override
    public void perform(final UiController uiController, final View view)
    {
        TextView tv = (TextView)view;//we matched
        if(tv != null && tv.requestFocusFromTouch())//get focus so drawables are visible
        {
            //get the bounds of the drawable image
            Rect drawableBounds = tv.getCompoundDrawables()[drawableLocation].getBounds();

            //calculate the drawable click location for left, top, right, bottom
            final Point[] clickPoint = new Point[4];
            clickPoint[Left] = new Point(tv.getLeft() + (drawableBounds.width() / 2), (int)(tv.getPivotY() + (drawableBounds.height() / 2)));
            clickPoint[Top] = new Point((int)(tv.getPivotX() + (drawableBounds.width() / 2)), tv.getTop() + (drawableBounds.height() / 2));
            clickPoint[Right] = new Point(tv.getRight() + (drawableBounds.width() / 2), (int)(tv.getPivotY() + (drawableBounds.height() / 2)));
            clickPoint[Bottom] = new Point((int)(tv.getPivotX() + (drawableBounds.width() / 2)), tv.getBottom() + (drawableBounds.height() / 2));

            if(tv.dispatchTouchEvent(MotionEvent.obtain(android.os.SystemClock.uptimeMillis(), android.os.SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, clickPoint[drawableLocation].x, clickPoint[drawableLocation].y, 0)))
                tv.dispatchTouchEvent(MotionEvent.obtain(android.os.SystemClock.uptimeMillis(), android.os.SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, clickPoint[drawableLocation].x, clickPoint[drawableLocation].y, 0));
        }
    }

    @IntDef({ Left, Top, Right, Bottom })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Location{}
}

这篇关于使用Espresso单击EditText的可绘制对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆