I have a Snackbar
which is as follows:
However, if the drop down of the AutoCompleteTextView
is too long, the drop down will block the Snackbar
.
As you can see in the above image, the Snackbar
is actually showing. However, its visibility is blocked by the long drop down. You can see from the above image
I try to use the following Snackbar code
. Adding bringToFront()
doesn't help much.
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
is a 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" />
Is there any good way, to avoid Snackbar
from being covered by AutoCompleteTextView
's drop down?
I might have a solution for that case. Of course, there are some assumptions but maybe the solution would suit you.
The key here is putting AutoCompleteTextView
inside CoordinatorLayout
and add custom CoordinatorLayout.Behavior
to it.
Create appropriate Behavior
for your class:
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;
}
}
Override a method layoutDependsOn
:
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, AutoCompleteTextView child, View dependency) {
return dependency instanceof Snackbar.SnackbarLayout;
}
Get reference to AutoCompleteTextView
popup view:
Unfortunately I haven't found a simple solution for that. However can be done via reflection.
@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;
}
Override onDependentViewChanged
method:
@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);
}
Apply the behavior to AutocompleteTextView
in .xml
:
app:layout_behavior="com.example.package.AutoCompleteTextViewBehaviour"/>
Of course this is a very basic solution, that for example does not animate list height, but I think this is a good start. Here is the full gist.