将Snackbar置于最高z顺序,以避免被AutoCompleteTextView下拉阻止

Che*_*eng 9 android autocompletetextview android-windowmanager android-snackbar android-coordinatorlayout

我有一个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();
}
Run Code Online (Sandbox Code Playgroud)

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" />
Run Code Online (Sandbox Code Playgroud)

有没有什么好办法可以避免SnackbarAutoCompleteTextView摔倒?

R. *_*ski 7

对于那种情况,我可能有一个解决方案.当然,有一些假设,但也许解决方案适合你.

这里的关键是放入AutoCompleteTextView内部CoordinatorLayoutCoordinatorLayout.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;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 覆盖方法layoutDependsOn:

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, AutoCompleteTextView child, View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 应用行为AutocompleteTextView.xml:

    app:layout_behavior="com.example.package.AutoCompleteTextViewBehaviour"/>
    
    Run Code Online (Sandbox Code Playgroud)

当然这是一个非常基本的解决方案,例如没有动画列表高度,但我认为这是一个好的开始.这是完整的要点.


Tin*_*ran 5

您可以计算并调整弹出窗口的高度作为替代.在下图中,我将下拉高度设置为:

textView.viewTreeObserver.addOnGlobalLayoutListener {
  textView.dropDownHeight = snackbarView.top - textView.bottom
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

此计算适用于建议列表的高度足够长的情况.您可能希望将该属性设置为WRAP_CONTENT.

据我所知,除非你直接添加SnackBar,否则无法更改"z-order" WindowManager.AutoCompleteTextView内部ListPopupWindow用于显示建议弹出ListPopupWindow窗口并且窗口类型为WindowManager.LayoutParams.TYPE_APPLICATION_PANEL= 1000,高于活动窗口类型WindowManager.LayoutParams.TYPE_APPLICATION= 2.