Coloque Snackbar en el orden z más alto para evitar ser bloqueado por AutoCompleteTextView desplegable

Tengo un Snackbar que es como sigue:

Introduzca aquí la descripción de la imagen

Sin embargo, si la lista desplegable de AutoCompleteTextView es demasiado larga, la lista desplegable bloqueará la Snackbar .

Introduzca aquí la descripción de la imagen

Como se puede ver en la imagen anterior, la Snackbar está mostrando. Sin embargo, su visibilidad está bloqueada por la larga caída hacia abajo. Usted puede ver de la imagen de arriba

Intento utilizar el siguiente Snackbar code . Añadir bringToFront() no ayuda mucho.

 private void showSnackbar(String message) { Snackbar snackbar = Snackbar.make(getActivity().findViewById(R.id.content), message, Snackbar.LENGTH_LONG); snackbar.getView().bringToFront(); snackbar.show(); } 

R.id.content es un CoordinatorLayout :

  <android.support.design.widget.CoordinatorLayout android:id="@+id/content" android:background="?attr/MyActivityBackground" android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="?attr/headerShadow" /> 

¿Hay alguna buena manera, para evitar Snackbar de ser cubierto por AutoCompleteTextView 's desplegable?

Podría tener una solución para ese caso. Por supuesto, hay algunas suposiciones, pero tal vez la solución le conviene.

La clave aquí es poner AutoCompleteTextView dentro de CoordinatorLayout y añadir CoordinatorLayout.Behavior personalizado a ella.

  1. Cree el Behavior apropiado para su clase:

     public class AutoCompleteTextViewBehaviour extends CoordinatorLayout.Behavior<AutoCompleteTextView> { public AutoCompleteTextViewBehaviour(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, AutoCompleteTextView child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; } } 
  2. Anular un método layoutDependsOn :

     @Override public boolean layoutDependsOn(CoordinatorLayout parent, AutoCompleteTextView child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; } 
  3. Obtener referencia a la vista emergente AutoCompleteTextView :

    Lamentablemente no he encontrado una solución simple para eso. Sin embargo se puede hacer a través de la reflexión.

     @Nullable private View getPopupList(AutoCompleteTextView child) { try { Field popupField; Class clazz; if (child instanceof AppCompatAutoCompleteTextView) { clazz = child.getClass().getSuperclass(); } else { clazz = child.getClass(); } popupField = clazz.getDeclaredField("mPopup"); popupField.setAccessible(true); ListPopupWindow popup = (ListPopupWindow) popupField.get(child); Field popupListViewField = popup.getClass().getDeclaredField("mDropDownList"); popupListViewField.setAccessible(true); return (View) popupListViewField.get(popup); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } 
  4. onDependentViewChanged override onDependentViewChanged :

     @Override public boolean onDependentViewChanged(CoordinatorLayout parent, final AutoCompleteTextView child, View dependency) { if (popupList == null) { popupList = getPopupList(child); if (popupList == null) { return super.onDependentViewChanged(parent, child, dependency); } } int dropdownBottom = child.getBottom() + child.getDropDownVerticalOffset() + popupList.getHeight(); int snackBarTop = dependency.getTop(); int difference = dropdownBottom - snackBarTop; if (difference > 0) { child.setDropDownHeight(popupList.getHeight() - difference); return true; } else { child.setDropDownHeight(ViewGroup.LayoutParams.WRAP_CONTENT); } return super.onDependentViewChanged(parent, child, dependency); } 
  5. Aplique el comportamiento a AutocompleteTextView en .xml :

     app:layout_behavior="com.example.package.AutoCompleteTextViewBehaviour"/> 

Por supuesto, esta es una solución muy básica, que por ejemplo no anima la altura de la lista, pero creo que esto es un buen comienzo. Aquí está la esencia completa.

Puede calcular y ajustar la altura de la ventana emergente como una alternativa. En la siguiente imagen, estoy configurando la altura de la lista desplegable como abajo:

 textView.viewTreeObserver.addOnGlobalLayoutListener { textView.dropDownHeight = snackbarView.top - textView.bottom } 

Introduzca aquí la descripción de la imagen

Este cálculo es para el caso en que la altura de la lista de sugerencias es lo suficientemente larga. Es posible que desee establecer esa propiedad en WRAP_CONTENT en WRAP_CONTENT lugar.

Por lo que sé, no es posible cambiar el "orden z" a menos que añada la barra de Snack directamente al WindowManager . AutoCompleteTextView internamente está usando ListPopupWindow para mostrar la ventana de sugerencias y ListPopupWindow tiene el tipo de ventana de WindowManager.LayoutParams.TYPE_APPLICATION_PANEL = 1000 que es mayor que el tipo de ventana de Activity que es de WindowManager.LayoutParams.TYPE_APPLICATION = 2.

¿Por qué no acaba de establecer android:dropDownHeight a un valor fijo dp ? Incluso puede definirlo para que se base dinámicamente en el tamaño de la pantalla por referencia a un recurso de dimension . Es una línea de código, resuelve su problema, fácil de mantener y de entender (en seis meses usted se preguntará, para qué se utiliza todo el material de Behavior ).

Pienso que usted tiene que tomar muchos piensa en la consideración:

  • Debe haber espacio para todos. Teclado, snackbar y autocompletar Textview
  • No puede cambiar la altura del teclado (por su aplicación), por lo que debe cambiar la altura del Autocompletar TextView por encima de la barra de menús (que está por encima del teclado)

Paso 1. Implementar un nuevo comportamiento

Es necesario comprobar si el dispositivo operativo admite snackbar.

 public class MoveUpwardBehavior extends CoordinatorLayout.Behavior<View> { private static final boolean SNACKBAR_BEHAVIOR_ENABLED; @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return SNACKBAR_BEHAVIOR_ENABLED && dependency instanceof Snackbar.SnackbarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); child.setTranslationY(translationY); return true; } static { SNACKBAR_BEHAVIOR_ENABLED = Build.VERSION.SDK_INT >= 11; } } 

Paso 2. Implementar vista personalizada para que podamos aplicar MoveUpwardBehavior a ella.

En este caso, hacemos que LinearLayout interactúe con snackbar. Es muy fácil, como se ha dicho, pasar la clase a la anotación DefaultBehavior.

 @CoordinatorLayout.DefaultBehavior(MoveUpwardBehavior.class) public class CustomLinearLayout extends LinearLayout { public CustomLinearLayout(Context context) { super(context); } public CustomLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } } 

Paso 3. Casi Terminado!

Añadir CustomLinearLayout en el diseño. Recuerde, debe ser incluido por CoordinatorLayout!

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.alisondemo.musicgenre.CustomLinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> ... </com.example.alisondemo.musicgenre.CustomLinearLayout> </android.support.design.widget.CoordinatorLayout> 

Pero … ¿por qué ni siquiera tenemos que implementar el comportamiento para FAB?

Forme el código fuente de la clase android.support.design.widget.FloatingActionButton, como puede ver:

@DefaultBehavior (FloatingActionButton.Behavior.class) public class FloatingActionButton extends ImageView {… Sí, en realidad tiene su propio comportamiento implementado.

Conclusión

Podemos implementar cualquier tipo de comportamiento que queramos en cualquier punto de vista. Debe ser muy interesante. 🙂

Usted puede ver sólo demo: http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior

El código fuente completo está ahora en GitHub https://github.com/Alishuang/MusicGenre

  • Android cómo hacer que AutoCompleteTextView funcione como cuadro de búsqueda de google
  • AutoCompleteTextView con dominios de correo electrónico android
  • Cómo agregar indicador de carga a AutoCompleteTextView
  • Cómo Agregar y eliminar las burbujas de contacto correctamente en multiautocompletetextview con espacio tokenizer como gmail al campo en android
  • Barra de Acción Android SearchView as Autocomplete?
  • Sugerencias de AutoCompleteTextView en modo horizontal
  • Cómo encontrar la posición del elemento en un AutoCompletetextview lleno de matriz
  • AutoCompleteTextView.isPopupShowing () siempre es FALSO
  • Cómo configurar setOnClickListener para AutoCompleteTextView?
  • AutoCompleteTextView recorta la última fila
  • Cómo agregar espacio a la sugerencia de AutoCompleteTextView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.