personalizar - toolbar android example
La barra de herramientas de Android appcompat se estira cuando Searchview se enfoca (10)
Estoy actualizando una aplicación para usar la nueva Toolbar
de Toolbar
lugar de la Toolbar
de ActionBar
normal. En mi aplicación, el usuario debe poder seleccionar un contacto de su lista de contactos. Para ello, he añadido un SearchView
al menú. Los contactos ya están en la lista; SearchView
se usa para filtrar la lista usando el método ArrayAdapter.getFilter()
.
Todo funcionó bien usando la ActionBar
, pero la altura de la Toolbar
de Toolbar
se estira justo detrás del teclado. Al usar la inspección XML del monitor del dispositivo Android, puedo ver que ListView
existe detrás de mi teclado.
Casi parece como si SearchView
quisiera mostrar sugerencias, pero no tengo tal cosa configurada. ¿Alguna idea de qué está mal?
Las imágenes ilustran el problema. Muestran el estado normal, expandido y enfocado de SearchView
.
Este es mi menú XML:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_forwarding_contact_search"
app:showAsAction="always"
android:title="@string/forwarding_contact_search"
app:actionViewClass="android.support.v7.widget.SearchView"
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"/>
</menu>
Editar Darle a la barra de herramientas una altura fija no resuelve el problema, ya que hará que SearchView
desaparezca cuando tenga el foco. Cambiar la gravedad de cualquiera de los elementos parece no tener ningún efecto en SearchView
.
En caso de que esté usando un EditText dentro de la barra de herramientas, agregando "flagNoExtractUi" en imeOptions, resolverá el área de edición de estiramiento.
EditText para Search Action sin estiramiento:
android:id="@+id/toolbar_editText"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:inputType="text"
android:imeOptions="actionSearch|flagNoExtractUi"
android:singleLine="true" />
La respuesta aceptada funciona bien, sin embargo, necesitaba una alternativa que permitiera ver la barra de herramientas en la barra de estado translúcida.
El problema es que la barra de herramientas usa rellenos para cubrir los componentes del sistema. Como resultado, el relleno del fondo de la barra de herramientas se configura a la altura del teclado suave cada vez que aparece el teclado. La solución fue restablecer el relleno antes de llamar a super.onMeasure en mi clase personalizada de la barra de herramientas:
public class MyToolbar extends Toolbar {
(...)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), 0);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
La solución más simple sin cambiar xml y mantener la barra de sistema translúcida es agregar: kotlin:
toolbar.setOnApplyWindowInsetsListener { toolbar, windowInsets ->
toolbar.updatePadding(
windowInsets.systemWindowInsetLeft,
windowInsets.systemWindowInsetTop,
windowInsets.systemWindowInsetRight,
0
)
windowInsets.consumeSystemWindowInsets()
}
por favor, compruebe si su fitsSystemWindows=true
se colocan correctamente
Me encontré con un problema similar y la configuración showAsAction="always|collapseActionView"
dentro del elemento del menú de búsqueda (menu.xml) resolvió el estiramiento de la barra de herramientas por mí.
Me gustaría compartir mi experiencia, pero antes de eso quiero dejar este comentario. Hasta ahora, realmente encuentro este CoordinatorLayout
shenanigans con errores y no es digno de ser eliminado en el SDK. Es solo buggy. Cuando se comporta de forma errática, la arquitectura en el diseño xml no es de gran ayuda para averiguar qué está pasando. Seguí los examples religiosamente y ninguno de ellos funcionó.
Dicho esto, estoy usando la versión v24.0.2 de las herramientas de compilación (la última versión de este documento) y mi situación puede ser diferente a la del resto. Así que estoy poniendo esta respuesta junto con otras respuestas aquí.
En mi caso, estoy usando esta library para NavigationDrawer
Como indicaron algunas respuestas aquí, es el cajón de navegación. Intenté no usar esa biblioteca y todavía tener el problema. Tengo CoordinatorLayout
como el diseño principal de mis dos actividades e inserta programáticamente NavigationDrawer
según las instrucciones del autor de la biblioteca. La Toolbar
expansión del tamaño de la pantalla cuando se enfoca en un texto de EditText
todavía está allí. Por lo tanto, en mi caso, el problema no viene de ahí.
Esto es lo que hice en mi caso:
fitsSystemWindows
del diseño de CoordinatorLayout
de la actividad. Contrariamente a lo que otras personas sugirieron aquí.
Estoy pegando todo el diseño de mi actividad aquí:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinatorlayout_homescreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.HomeScreenActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingtoolbarlayout_homescreen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="64dp"
app:expandedTitleMarginEnd="48dp"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_homescreen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="@+id/framelayout_homescreen"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
<!--
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_homescreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
-->
</android.support.design.widget.CoordinatorLayout>
Hice esto en otra actividad y funciona como se esperaba. Ya no tengo la Toolbar
expandible. Pero este problem ocurrió. Estoy a punto de sacarme el pelo. La barra de estado se volvió blanca. La solución de Phoenix Wang en ese post me la arregló y cito su respuesta:
Encontré la respuesta en este enlace: el color de la barra de estado no cambia con el diseño relativo como elemento raíz
Así que resulta que tenemos que eliminar el
<item name="android:statusBarColor">@android:color/transparent</item> in
styles.xml (v21). Y funciona bien para mí.
Mi única preocupación es cómo se mantendrá esta solución en las próximas actualizaciones. CoordinatorLayout
no debe comportarse así.
Ok, lo he descubierto. No hubo ningún problema con SearchView
, porque lo mismo sucedió con los EditText
normales que se colocaron normalmente dentro de un xml de diseño. La Toolbar
tampoco fue el problema.
Creé una actividad vacía y jugué con todo lo que cambié en mi aplicación y finalmente llegué a mi tema. En KitKat y más tarde tenía <item name="android:windowTranslucentStatus">true</item>
configurado en el tema, por lo que el cajón de navegación aparecería detrás de la barra de estado.
Deshabilitar / eliminar esto resolvería el problema. Esto me recordó la android:fitsSystemWindows="true"
. Se establece en la Toolbar
, pero no en el diseño XML de la actividad principal que contiene DrawerLayout
. Supongo que DrawerLayout
ajusta a las ventanas del sistema. Por ejemplo, no hay fitSystemWindows
propiedad fitSystemWindows
aquí:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DashboardActivity">
La actividad donde ocurrió el problema no tenía un NavigationDrawer
, era una actividad nueva. La configuración de android:fitsSystemWindows="true"
en el nodo raíz del diseño de la actividad hizo que las cosas funcionaran bien.
Entonces, para que cualquiera pueda leer esto: si tiene <item name="android:windowTranslucentStatus">true</item>
en su tema, asegúrese de que cualquier nodo raíz que contenga una barra de herramientas contenga un android:fitsSystemWindows="true"
.
Muestra de trabajo
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button" />
</LinearLayout>
</LinearLayout>
Parece una pregunta antigua, pero quiero abordar la causa real de este problema.
De hecho, fitsSystemWindows no solo agrega las inserciones de la barra de estado en el relleno de tus vistas, sino también la altura del teclado. Entonces, cuando se mostró el teclado, su barra de herramientas (que es la vista que consume las inserciones de las ventanas) obtendrá un relleno inferior igual a la altura de su teclado.
Mover fitSystemWindows al nodo raíz resuelve este problema, pero a veces no podemos hacerlo, por ejemplo, necesitamos el fondo de la barra de herramientas para llenar la barra de estado.
Entonces, la solución real para este problema, creo, es decirle a la vista que solo consuma inserciones superiores. Afortunadamente, Android nos ofrece un método para hacerlo.
private static final View.OnApplyWindowInsetsListener CONSUME_TOP_INSET_LISTENER = new View.OnApplyWindowInsetsListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH)
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
int b = v.getPaddingBottom();
int l = v.getPaddingLeft();
int r = v.getPaddingRight();
v.setPadding(l, insets.getSystemWindowInsetTop(), r, b);
int il = insets.getSystemWindowInsetLeft();
int ir = insets.getSystemWindowInsetRight();
int ib = insets.getSystemWindowInsetBottom();
return insets.replaceSystemWindowInsets(il, 0, ir, ib);
}
};
public static void makeViewConsumeTopWindowInsetsOnly(@NonNull View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
view.setOnApplyWindowInsetsListener(CONSUME_TOP_INSET_LISTENER);
}
}
Agregue el código anterior a algún lugar y llame a este método con la vista que desee para consumir las inserciones superiores.
Tuve el mismo problema como este, pero no ayudé en las respuestas anteriores, pero después de mucha búsqueda encontré algo.
puede ayudarte también !!
después de agregar este atributo en la toolbar
de toolbar
android:layout_height="?attr/actionBarSize"
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/myPrimaryColor"
android:minHeight="@dimen/abc_action_bar_default_height_material" >
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@color/myTextPrimaryColor"
android:layout_gravity="center" />
</android.support.v7.widget.Toolbar>
Tuve el mismo problema con SearchView en una barra de herramientas con TextView y Spinner. Al cerrar el SearchView (ya sea presionando el botón Atrás de la barra de herramientas o cambiando a una pestaña diferente en el ViewPager), la barra de herramientas se extendía justo debajo de la parte superior del teclado.
Lo resolví colocando un diseño adicional alrededor de las vistas en mi barra de herramientas.
Antes de:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
Después
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
Tuve el mismo problema que OP, probé la android:fitsSystemWindows="true"
, pero se resolvió a medias: la vista de búsqueda no se expandió más pero la barra de notificaciones (parte superior de la pantalla) se volvió totalmente blanca (como el fondo del diseño) ) en lugar de rojo (mi tema de aplicación).
Encontré una forma alternativa y está funcionando a la perfección, así que para aquellos que están atascados, intente esto:
En su manifiesto, solo agregue esta línea en su sección de actividades:
android: windowSoftInputMode = "adjustPan"
Ejemplo:
<activity
android:name=".MainActivity"
android:windowSoftInputMode="adjustPan"
android:label="My main activity" >
</activity>