Поместите Snackbar в наивысшем порядке z, чтобы избежать блокировки при выводе AutoCompleteTextView

У меня есть Snackbar которая выглядит следующим образом:

Введите описание изображения здесь

Однако, если выпадающее значение AutoCompleteTextView слишком велико, выпадающее меню блокирует Snackbar .

Введите описание изображения здесь

Как видно из приведенного выше изображения, Snackbar на самом деле показывает. Однако его видимость блокируется длительным падением. Вы можете видеть из приведенного выше изображения

Я пытаюсь использовать следующий Snackbar code . Добавление bringToFront() не очень помогает.

 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.contentCoordinatorLayout :

  <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" /> 

Есть ли хороший способ, чтобы избежать того, что Snackbar будет закрыт приложением AutoCompleteTextView ?

Solutions Collecting From Web of "Поместите Snackbar в наивысшем порядке z, чтобы избежать блокировки при выводе AutoCompleteTextView"

У меня может быть решение для этого случая. Конечно, есть некоторые предположения, но, возможно, решение подойдет вам.

Ключевым моментом здесь является включение AutoCompleteTextView внутри CoordinatorLayout и добавление к нему пользовательского CoordinatorLayout.Behavior .

  1. Создайте соответствующее Behavior для своего класса:

     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. Переопределить метод layoutDependsOn :

     @Override public boolean layoutDependsOn(CoordinatorLayout parent, AutoCompleteTextView child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; } 
  3. Получить ссылку на всплывающее окно AutoCompleteTextView :

    К сожалению, я не нашел для этого простого решения. Однако это можно сделать путем отражения.

     @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 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. Примените поведение к AutocompleteTextView в .xml :

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

Конечно, это очень простое решение, которое, например, не обновляет высоту списка, но я думаю, что это хорошее начало. Вот полный смысл .

Вы можете рассчитать и настроить высоту всплывающего окна в качестве альтернативы. На следующем рисунке я устанавливаю высоту выпадающего списка ниже:

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

Введите описание изображения здесь

Этот расчет предназначен для случая, когда высота списка предложений достаточно длинная. Возможно, вы захотите установить это свойство на WRAP_CONTENT .

Насколько мне известно, изменить «z-порядок» невозможно, если вы не добавите SnackBar непосредственно в WindowManager . AutoCompleteTextView внутренне использует ListPopupWindow для отображения всплывающих ListPopupWindow а ListPopupWindow имеет тип окна WindowManager.LayoutParams.TYPE_APPLICATION_PANEL = 1000, который выше, чем тип окна Activity, который имеет WindowManager.LayoutParams.TYPE_APPLICATION = 2.

Почему бы просто не установить android:dropDownHeight до фиксированного значения dp ? Вы даже можете определить его динамически на основе размера экрана по ссылке на ресурс dimension . Это одна строка кода, она решает вашу проблему, проста в обслуживании и понимании (через шесть месяцев вы спросите себя, для чего используется весь материал Behavior ).

Я думаю, вы должны принять во внимание многие мысли:

  • Должно быть место для всех. Клавиатура, закусочная и автозаполнение Textview
  • Вы не можете изменить высоту клавиатуры (своим приложением), поэтому вам нужно изменить высоту автозаполнения TextView, чтобы быть выше закусочной (которая находится над клавиатурой)

Шаг 1. Внедрение нового поведения

Необходимо проверить, поддерживает ли операционное устройство закусочную.

 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; } } 

Шаг 2. Внедрите пользовательский вид, чтобы мы могли применить MoveUpwardBehavior к нему.

В этом случае мы делаем весь LinearLayout взаимодействующим с закусочной. Это очень просто, как здесь сказано, просто передать класс в аннотацию 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); } } 

Шаг 3. Почти все!

Добавьте CustomLinearLayout в макет. Помните, что он должен быть включен 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> 

Но … почему нам даже не нужно внедрять поведение для FAB?

Создайте исходный код класса android.support.design.widget.FloatingActionButton, как вы можете видеть:

@DefaultBehavior (FloatingActionButton.Behavior.class) открытый класс FloatingActionButton расширяет ImageView {… Да, на самом деле у него есть собственное поведение.

Вывод

Мы можем реализовать любое поведение, которое мы хотим в любых представлениях. Это должно быть очень интересно. 🙂

Вы можете увидеть только демо: http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior

Полный исходный код теперь находится на GitHub https://github.com/Alishuang/MusicGenre