Android 仅当视图包含浮动操作按钮时才显示 snackbar 时,espresso 测试冻结
Android espresso test freezes when snackbar is showing only when view contains Floating Action Button
我认为这是一个错误,但我可能做错了什么。
我的布局非常简单,只包含一个浮动操作按钮:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentCoordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/layoutWithoutContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/stopButton"
android:src="@drawable/ic_stop_white_24px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
app:layout_anchor="@id/layoutWithoutContent"
app:backgroundTint="@color/colorPrimary"
app:layout_anchorGravity="bottom|right|end"/>
我的activity只继承了onCreate方法包含:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CoordinatorLayout coordinatorLayout = findViewById(R.id.contentCoordinatorLayout);
Snackbar.make(coordinatorLayout, R.string.snackbar_message, Snackbar.LENGTH_LONG).show();
}
我写了一个 Espresso 测试,它只验证 Snackbar 在半秒内显示
@Rule
public ActivityTestRule<MainActivity> mainActivity = new ActivityTestRule<>(MainActivity.class, true, true);
@Test
public void testSnackbarIsShown() throws Exception { onView(withText(R.string.snackbar_message)).check(matches(isDisplayed()));
}
当我调试此测试时,onView(withText(R.string.snackbar_message)).check(matches(isDisplayed()));
在 快餐栏消失后 执行。
到目前为止,我找到了 3 种方法来解决这个问题,问题在以下情况下得到解决:
我将 FloatingActionButton 的 anchorGravity 更改为顶部:app:layout_anchorGravity="top|right|end"
我完全删除了 FloatingActionButton
将 Snackbar 的第一个参数更改为使用 findViewById(android.R.id.content)
。但这并不会在 snackbar 出现时将 FloatingActionButton 向上推。
正如我所说,我认为这是一个错误,但如果我在这里做错了什么,请告诉我。
您在 xml 中构建布局的方式使 UI 在 Snackbar 与 FAB 按钮交互时不断更新。
您找到的三个解决方案有一个共同点,它们都消除了 Snackbar 和 FAB 按钮之间的交互。当您将重力设置为 TOP 时,Snackbar 不会按下按钮,因为它们位于屏幕的不同端。当您完全移除 FAB 按钮时,也没有交互。当您更改传递给 Snackbar 构建器的视图时,也没有交互,因为 Snackbar 显示在按钮顶部。
如果您在“设置”>“开发人员选项”中启用 Show Surface Updates
,您实际上会在显示 Snakcbar 时看到 UI 正在更新。 Espresso 轮询 UI 线程,试图找出它何时空闲。由于 Snackbar 使 UI 线程处于忙碌状态,因此 Espresso 不会 运行 测试代码,直到 Snackbar 消失。
似乎与:
有关
app:layout_anchor="@id/layoutWithoutContent"
app:layout_anchorGravity="bottom|right|end"
如果您将它们替换为:
android:layout_gravity="bottom|end"
生成的布局看起来相同,测试 运行 正确。如果您启用了 Show Surface Updates
,您会看到 UI 在显示 Snackbar 时没有更新。
我认为这是一个错误,但我可能做错了什么。
我的布局非常简单,只包含一个浮动操作按钮:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contentCoordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/layoutWithoutContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/stopButton"
android:src="@drawable/ic_stop_white_24px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
app:layout_anchor="@id/layoutWithoutContent"
app:backgroundTint="@color/colorPrimary"
app:layout_anchorGravity="bottom|right|end"/>
我的activity只继承了onCreate方法包含:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CoordinatorLayout coordinatorLayout = findViewById(R.id.contentCoordinatorLayout);
Snackbar.make(coordinatorLayout, R.string.snackbar_message, Snackbar.LENGTH_LONG).show();
}
我写了一个 Espresso 测试,它只验证 Snackbar 在半秒内显示
@Rule
public ActivityTestRule<MainActivity> mainActivity = new ActivityTestRule<>(MainActivity.class, true, true);
@Test
public void testSnackbarIsShown() throws Exception { onView(withText(R.string.snackbar_message)).check(matches(isDisplayed()));
}
当我调试此测试时,onView(withText(R.string.snackbar_message)).check(matches(isDisplayed()));
在 快餐栏消失后 执行。
到目前为止,我找到了 3 种方法来解决这个问题,问题在以下情况下得到解决:
我将 FloatingActionButton 的 anchorGravity 更改为顶部:
app:layout_anchorGravity="top|right|end"
我完全删除了 FloatingActionButton
将 Snackbar 的第一个参数更改为使用
findViewById(android.R.id.content)
。但这并不会在 snackbar 出现时将 FloatingActionButton 向上推。
正如我所说,我认为这是一个错误,但如果我在这里做错了什么,请告诉我。
您在 xml 中构建布局的方式使 UI 在 Snackbar 与 FAB 按钮交互时不断更新。
您找到的三个解决方案有一个共同点,它们都消除了 Snackbar 和 FAB 按钮之间的交互。当您将重力设置为 TOP 时,Snackbar 不会按下按钮,因为它们位于屏幕的不同端。当您完全移除 FAB 按钮时,也没有交互。当您更改传递给 Snackbar 构建器的视图时,也没有交互,因为 Snackbar 显示在按钮顶部。
如果您在“设置”>“开发人员选项”中启用 Show Surface Updates
,您实际上会在显示 Snakcbar 时看到 UI 正在更新。 Espresso 轮询 UI 线程,试图找出它何时空闲。由于 Snackbar 使 UI 线程处于忙碌状态,因此 Espresso 不会 运行 测试代码,直到 Snackbar 消失。
似乎与:
有关app:layout_anchor="@id/layoutWithoutContent"
app:layout_anchorGravity="bottom|right|end"
如果您将它们替换为:
android:layout_gravity="bottom|end"
生成的布局看起来相同,测试 运行 正确。如果您启用了 Show Surface Updates
,您会看到 UI 在显示 Snackbar 时没有更新。