Поместите 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.content является 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" />
Есть ли какой-нибудь хороший способ, чтобы избежать Snackbar от того, чтобы быть покрытым падением AutoCompleteTextView?
6 ответов:
Возможно, у меня есть решение для этого случая. Конечно, есть некоторые предположения, но, возможно, решение вас устроит.
Ключ здесь заключается в том, чтобы поместить
AutoCompleteTextViewвнутрьCoordinatorLayoutи добавить к нему пользовательскийCoordinatorLayout.Behavior.Конечно, это очень простое решение, которое, например, не анимирует высоту списка, но я думаю, что это хорошее начало. Вот полнаясуть .
Создайте соответствующий
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; } }Переопределить метод
layoutDependsOn:@Override public boolean layoutDependsOn(CoordinatorLayout parent, AutoCompleteTextView child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; }Получить ссылку на
К сожалению, я не нашел для этого простого решения. Однако это можно сделать с помощью отражение.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; }Переопределение
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); }Примените поведение к
AutocompleteTextViewв.xml:app:layout_behavior="com.example.package.AutoCompleteTextViewBehaviour"/>
Вы можете рассчитать и настроить высоту всплывающего окна в качестве альтернативы. На следующем рисунке я устанавливаю высоту выпадающего списка следующим образом:
textView.viewTreeObserver.addOnGlobalLayoutListener { textView.dropDownHeight = snackbarView.top - textView.bottom }Это вычисление для случая, когда высота списка предложений достаточно велика. Вместо этого вы можете установить для этого свойства значение
Насколько мне известно, изменить "z-порядок" невозможно, если вы не добавите закусочную непосредственно кWRAP_CONTENT.WindowManager.AutoCompleteTextViewвнутренне используетListPopupWindow, чтобы показать всплывающее окно предложений иListPopupWindowимеет тип окнаWindowManager.LayoutParams.TYPE_APPLICATION_PANEL= 1000, который выше, чем тип окна действия, который имеетWindowManager.LayoutParams.TYPE_APPLICATION= 2.
Почему бы просто не установить
android:dropDownHeightв фиксированноеdpзначение? Вы даже можете определить его динамически на основе размера экрана, обратившись к ресурсуdimension. Это одна строка кода, она решает вашу проблему, проста в обслуживании и понимании (через полгода вы спросите себя, для чего используется весь материалBehavior).
Я думаю, что вы должны принять во внимание много мыслей:
- должно быть место для всех. клавиатура, закусочная и автозаполнение Textview
- Вы не можете изменить высоту клавиатуры (с помощью вашего приложения), поэтому вы должны изменить высоту автозаполнения TextView, чтобы быть выше закусочной (которая находится над клавиатурой)
В моем случае я мог бы заставить его работать с
setZ:Snackbar snackbar = Snackbar.make(container, text, Snackbar.LENGTH_LONG); snackbar.getView().setZ(200); snackbar.show();
Шаг 1. Реализовать новое поведение
Необходимо проверить, поддерживает ли операционное устройство 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; } }Шаг 2. Реализуйте пользовательский вид, чтобы мы могли применить к нему MoveUpwardBehavior.
В этом случае мы заставляем весь LinearLayout взаимодействовать с snackbar. Это очень просто, как здесь сказано, просто передайте класс в defaultbehavior аннотации.
Шаг 3. Почти Готово!@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); } }Добавьте CustomLinearLayout в макет. Помните, что он должен быть включен Координаторлай!
<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.поддержка.дизайн.штучка.Класс FloatingActionButton, как вы можете видеть:
@DefaultBehavior (FloatingActionButton.Поведение.класс) FloatingActionButton общественный класс расширяет графическое представление { ... Да, у него на самом деле реализовано собственное поведение.
Заключение
Мы можем реализовать любой тип поведения, который мы хотим, в любых представлениях. Это должно быть очень интересный. :)
Вы можете увидеть только демо: http://alisonhuang-blog.logdown.com/posts/290009-design-support-library-coordinator-layout-and-behavior
Полный исходный код теперь на GitHub https://github.com/Alishuang/MusicGenre


