【问题标题】:Swipe to Recycler View Item until displayed滑动到回收站查看项目直到显示
【发布时间】:2021-09-08 19:32:52
【问题描述】:

我有一个没有 ~~scrolling~~ 和 nestedScrollingEnabled=false 的嵌套回收器列表。我正在尝试向上滑动并通过其文本单击回收站项目。在确定何时滑动以及滑动多远时遇到问题。

更新:这可能有滚动,我可能需要用文本指定项目的 ViewHolder 而不是用文本的视图...正在试验...

  • parent_recycler_list
    • recycler_list
      • 列表项 A
      • 列表项 B
    • recycler_list
      • 列表项 A
      • 列表项 B

到目前为止,我能够找到该项目并尝试点击它:

Espresso.onView(
            CoreMatchers.allOf(
                ViewMatchers.withId(R.id.recycler_list),
                ViewMatchers.hasDescendant(recyclerViewItemWithText(text))
            )
        ).perform(
            RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
                recyclerViewItemWithText(text),
                ViewActions.click()
            )
        )
fun recyclerViewItemWithText(text: String) = object : BoundedMatcher<View, View>(View::class.java) {
    override fun describeTo(description: Description?) {
        description?.appendText("Searching for text with: $text")
    }

    override fun matchesSafely(item: View?): Boolean {
        val views = ArrayList<View>()
        item?.findViewsWithText(views, text, View.FIND_VIEWS_WITH_TEXT)

        return when (views.size) {
            1 -> true
            else -> false
        }
    }
}

这仅在显示列表项时自行起作用。 我尝试滑动直到显示视图项:

Espresso.onView(ViewMatchers.withId(R.id.parent_recycler_list)).perform(
            ViewActions.repeatedlyUntil(
                ViewActions.swipeUp(),
                Matchers.allOf(
                    ViewMatchers.hasDescendant(ViewMatchers.withText(text)),
                    isCompletelyDisplayed()
                ), 10
            )
        )

这将始终至少滑动一次...并且可以滑过我正在寻找的视图项。

有没有一种方法可以让我更精确地确定滑动的时间和距离?

我还是个新手,对视图持有者的自定义滑动操作了解不多。谢谢

尝试使用nestedScrollTo()时

java.lang.RuntimeException:将不会执行操作,因为 目标视图与以下一项或多项约束不匹配: (视图具有有效的可见性=VISIBLE 并且是 a 的后代:(是 可从类分配:类 androidx.core.widget.NestedScrollView))

【问题讨论】:

    标签: android-recyclerview android-espresso


    【解决方案1】:

    如果您的嵌套回收器视图没有启用嵌套滚动,您可以简单地使用ViewActions.scrollTo(),但您需要先调整操作,因为它不支持NestedScrollView

    fun nestedScrollTo(): ViewAction = object : ViewAction {
    
        private val scrollTo = ViewActions.scrollTo()
    
        override fun getConstraints(): Matcher<View> {
            return Matchers.allOf(
                ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
                ViewMatchers.isDescendantOfA(Matchers.anyOf(ViewMatchers.isAssignableFrom(NestedScrollView::class.java))))
        }
    
        override fun getDescription(): String = scrollTo.description
    
        override fun perform(uiController: UiController, view: View) = scrollTo.perform(uiController, view)
    }
    

    然后使用新的自定义动作滚动,例如:

    onView(withText("query")).perform(nestedScrollTo(), click())
    

    如果可能,请避免在此用例中使用滑动,它们有时可能不可靠。

    【讨论】:

    • 感谢nestedScrollTo() 比我从espresso-testing-nestedscrollview-error-performing-scroll-to-on-view-with 尝试的其他脚本更干净所有失败,这就是我求助于滑动的原因...
    • 如果子回收器视图没有启用嵌套滚动,或者你也可以尝试onView(parent_recycler_view).perform(RecyclerViewActions.scrollTo(child_recycler_view_2)),然后onView(child_recycler_view_2).perform(RecyclerViewActions.scrollTo(...)),希望这个也可以!仅当您的回收站视图放置在嵌套滚动视图中时,上述答案才有效。
    【解决方案2】:

    感谢Aaron 提供了清晰的脚本和巧妙的描述,让我有了全新的视角。

    总体而言,我认为由于 BoundedMatcher,我已经远离了 scrollTo(),而应该改用 hasDescendant(withText("text"))

    现在使用 scrollTo 回到正轨,但在层次结构中不存在回收器视图时仍使用 swipeUp()。 “第二个嵌套回收器视图在显示之前不存在......”

    private fun tapRecyclerItem(titleText: String) {
            for (i in 0 until MAX_ATTEMPTS) {
                try {
                    findRecyclerViewItemByIdAndText(R.id.recycler_list, text)
                        .tapRecyclerViewItem(text)
                    break
                }
                //View is not in hierarchy, yet
                catch (e: NoMatchingViewException) {
                    onView(withId(R.id.parent_recycler_list))
                        .swipeUpUntilRecyclerViewItemIsDisplayed(text)
                }
            }
        }
    
    fun findRecyclerViewItemByIdAndText(@IdRes id: Int, text: String): ViewInteraction {
        return onView(allOf(withId(id), hasDescendantWithText(text)))
    }
    
    fun ViewInteraction.tapRecyclerViewItem(text: String) {
        this.perform(
            actionOnItem<ViewHolder>(hasDescendantWithText(text), scrollTo()),
            actionOnItem<ViewHolder>(hasDescendantWithText(text), click())
        )
    }
    
    fun hasDescendantWithText(text: String): Matcher<View> {
        return Matchers.allOf(
            hasDescendant(withText(text)),
            withEffectiveVisibility(VISIBLE)
        )
    }
    
    fun ViewInteraction.swipeUpUntilRecyclerViewItemIsDisplayed(text: String) {
        this.perform(repeatedlyUntil(
            swipeUp(),
            hasDescendantWithText(text), 10)
        )
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2021-08-03
      • 1970-01-01
      相关资源
      最近更新 更多