Cómo abrir una pestaña en Espresso
-
21-12-2019 - |
Pregunta
¿Cómo puedo abrir una pestaña en la prueba de Espresso?traté de hacer Espresso.onView(ViewMatchers.withId(R.id.practice_results_tab)).perform(ViewActions.click());
, pero eso no funciona.En ese código abrí Diseño de esta pestaña.Ahí está el archivo XML:
<TabHost
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/practice_tabHost">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="@+id/practice_settings_tab"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/practice_results_tab"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
¿Qué ID debo usar para abrir la pestaña?
Error en logcat:
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
at least 90 percent of the view's area is displayed to the user.
Target view: "LinearLayout{id=2131296384, res-name=practice_results_tab, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}"
Solución
Código completado
Realmente necesita agregar código para que podamos darle una respuesta adecuada.Supongo que usaste TabHost y TabWidget de la forma en que lo hace este ejemplo: https://maxalley.wordpress.com/2012/10/25/android-creating-a-tab-layout-with-tabhost-and-tabwidget/
He creado un proyecto de muestra en https://github.com/hanscappelle/SO-25016397
Entonces tu actividad podría verse así:
public class MainActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabHost tabHost = getTabHost();
// setNewTab(context, tabHost, tag, title, icon, contentID);
this.setNewTab(this, tabHost, "tab1", R.string.textTabTitle1, R.drawable.ic_tab_settings, R.id.practice_settings_tab);
this.setNewTab(this, tabHost, "tab2", R.string.textTabTitle2, R.drawable.ic_tab_results, R.id.practice_results_tab);
}
private void setNewTab(Context context, TabHost tabHost, String tag, int title, int icon, int contentID ){
TabSpec tabSpec = tabHost.newTabSpec(tag);
String titleString = getString(title);
tabSpec.setIndicator(titleString, context.getResources().getDrawable(android.R.drawable.star_on));
tabSpec.setContent(contentID);
tabHost.addTab(tabSpec);
}
}
Encontré otro ejemplo de código en https://maxalley.wordpress.com/2012/10/27/android-styling-the-tabs-in-a-tabwidget/ con un método auxiliar que inyecta un ImageView
para las pestañas.
private View getTabIndicator(Context context, int title, int icon) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.imageView);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setText(title);
return view;
}
Ahora se pone interesante porque de esta manera podemos establecer fácilmente una identificación o una etiqueta en estos inyectados. View
objetos y utilizarlos en Espresso.
Una solución:Etiquetar la vista
Si adapta ese asistente para aceptar una etiqueta para cada vista, el código del asistente se verá así:
private View getTabIndicator(Context context, int title, int icon, int viewId, String viewTag) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.image_view);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.text_view);
tv.setText(title);
tv.setTag(viewTag);
return view;
}
Si usa solo íconos, también puede configurar la ID en ImageView.
Y el código de Espresso para hacer clic en estas pestañas:
Espresso.onView(ViewMatchers.withTagValue(Matchers.is((Object)"tab1"))).perform(ViewActions.click());
Solución alternativa:usando Ver ID
Si opta por ID, necesita que estos ID estén definidos en algún lugar.Utilice un archivo de recursos de Android simple con algunas definiciones de ID.
El archivo de recursos de ID de vista, denominado /values/ids.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="tab1" type="id" />
</resources>
El ayudante adaptado:
private View getTabIndicator(Context context, int title, int icon, int viewId, String viewTag) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
ImageView iv = (ImageView) view.findViewById(R.id.image_view);
iv.setImageResource(icon);
TextView tv = (TextView) view.findViewById(R.id.text_view);
tv.setText(title);
tv.setId(viewId);
return view;
}
Si usa solo íconos, también puede configurar la ID en ImageView.
Y el código de Espresso para hacer clic en estas pestañas:
Espresso.onView(ViewMatchers.withId(R.id.tab1)).perform(ViewActions.click());
Acerca de TabHosts en general
¿Por qué usaste este TabHost en primer lugar?Tenga en cuenta que esta clase ya está en desuso.A ViewPager con pestañas o la barra de acciones podrían ser mejores opciones dependiendo de su caso de uso.
Utilice la herramienta VerJerarquía
En casos como este, el primer problema suele ser encontrar la vista adecuada.Para ello utilice el Ver jerarquía herramienta.Es parte del SDK de Android y se encuentra en el directorio de herramientas.
Puedes iniciarlo desde una línea de comando como esta:
cd ANDROID_SDK_LOCATION/tools
hierarchyviewer
O usar Estudio Android menú:Herramientas > Android > Monitor de dispositivo Android.Luego abra la perspectiva Vista de jerarquía desde el menú en el monitor del dispositivo:Ventana > Abrir perspectiva > Vista de jerarquía.
Prefiero la primera opción sólo porque el Monitor de dispositivo hace demasiado para nuestras intenciones.
Ahora use la Vista de diseño en combinación con la vista Propiedades de vista para encontrar el ID y las etiquetas de la vista que desea.
Algunas instrucciones sobre esta herramienta: http://developer.android.com/tools/debugging/debugging-ui.html
Otros consejos
lo único que me funciona es:
public void clickOnTab(String tabText) {
Matcher<View> matcher = allOf(withText(tabText),
isDescendantOfA(withId(R.id.ll_tab_container)));
onView(matcher).perform(click());
}
dónde ll_tab_container
es el diseño lineal para mi diseño de pestaña personalizado.y si tuviera una pestaña llamada "compras", la pasaría como pestañaTexto.
onview (withtext ("su etiqueta de la pestaña")). Realizar (haga clic en))
También es posible configurar una etiqueta en el texto de su pestaña sin utilizar un método de indicador personalizado.Esto se hace accediendo a la pestaña TextView
después de haber sido creado.
Utilizando el MainActivity
A partir del código de ejemplo de hcpl, se vería así:
public MainActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabHost tabHost = getTabHost();
// setNewTab(context, tabHost, tag, title, icon, contentID);
this.setNewTab(this, tabHost, "tab1", R.string.textTabTitle1, R.drawable.ic_tab_settings, R.id.practice_settings_tab);
this.setNewTab(this, tabHost, "tab2", R.string.textTabTitle2, R.drawable.ic_tab_results, R.id.practice_results_tab);
// Set custom tag on first tab
View tabView1 = tabHost.getTabWidget().getChildAt(0);
TextView tabView1Text = (TextView) signUpTabView.findViewById(android.R.id.title);
signUpTextTab.setTag("TAG_TAB_ONE");
// Set custom tag on second tab
View tabView2 = tabHost.getTabWidget().getChildAt(1);
TextView tabView1Text = (TextView) signUpTabView.findViewById(android.R.id.title);
signUpTextTab.setTag("TAG_TAB_TWO");
}
}
Luego, en tu prueba de Espresso, podrás acceder a pestañas como esta:
onView(withTagValue(Matchers.is((Object)"TAG_TAB_TWO"))).perform(click());