Snackbar 制作Toast遇到遮挡处理

Snackbar 制作Toast遇到遮挡处理

为什么要用Snackbar替代Toast

Toast If your app targets Android 12 (API level 31) or higher, its toast is limited to two lines of text and shows the application icon next to the text. Be aware that the line length of this text varies by screen size, so it's good to make the text as short as possible. 如果你的应用程序目标是Android 12(API级别31)或更高版本,其Toast仅限于两行文本,并在文本旁边显示应用程序图标。请注意,此文本的行长度因屏幕大小而异,因此最好使文本尽可能短。

If your app is in the foreground, consider using a snackbar instead of using a toast. Snackbars include user-actionable options, which can provide a better app experience.

If your app is in the background, and you want users to take some action, use a notification instead.

如果你的应用程序在前台,可以考虑使用Snackbar而不是Toast。Snackbar包括用户可操作的选项,可以提供更好的应用程序体验。

如果你的应用程序在后台,并且你希望用户采取一些行动,请使用Notification。

Snackbar局限性在于依附view,如何出现dialog或者popwindow等遮挡弹框将会被遮盖在后面。官方提的Notification可以作为后台弹窗,通常顶部弹出,展示效果和Toast存在着差异。另一种是将Snackbar制作成强行显示在应用最上方,需要借助WindowManager,还需要运行时权限申请。

Dialog 辅助 Snackbar制作不被遮挡的Snackbar

  • 定义一个全屏透明的Dialog作为snackbar的容器窗口
  • 给Dialog做一个延迟取消,时常和snackbar长短时长等同
  • 控制窗口透明度,两窗口叠加时透明度会受到影响
  • 页面销毁时要跳出方法不让重新创建
  • Dialog受制于actvity,无法跨页面显示
ini 复制代码
public static void show(final Context context, final String message, final int duration) {
    AppCompatActivity act = ((AppCompatActivity) context);
    if (act.isFinishing()) {
        return;
    }
    if (alertDialog != null && alertDialog.isShowing()) {
        alertDialog.dismiss();
    }
    Window win = act.getWindow();
    View rootView = win.getDecorView(); //activity.findViewById(android.R.id.content);
    alertDialog = new MaterialAlertDialogBuilder(context, R.style.MaterialDialogTheme).create();
    alertDialog.show();
    Window window = alertDialog.getWindow();
    WindowManager.LayoutParams params = window.getAttributes();
    params.width = WindowManager.LayoutParams.MATCH_PARENT;
    params.height = WindowManager.LayoutParams.MATCH_PARENT;
    params.dimAmount = 0.2f;
    window.setAttributes(params);
    window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    rootView.postDelayed(() -> {
        if (act==null||act.isFinishing()) {
            return;
        }
        if (alertDialog != null && alertDialog.isShowing()) {
            alertDialog.dismiss();
        }
    }, duration == Toast.LENGTH_SHORT ? 1500 : 2750);
    show(window.getDecorView(), message, duration);
}
ini 复制代码
public static Snackbar toast(View rootView, String message, int duration) {

    Snackbar mSnackbar =
            Snackbar.make(rootView, "Replace with your own action", duration);
    Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) mSnackbar.getView();
    layout.setBackgroundColor(Color.TRANSPARENT);
    layout.setElevation(0);
    layout.setPadding(0, 0, 0, 0);
    TextView textView =
            layout.findViewById(com.platform.view.R.id.snackbar_text);
    textView.setVisibility(View.GONE);

    View view = LayoutInflater.from(rootView.getContext()).inflate(com.platform.view.R.layout.customer_snackbar_toast, layout);
    AppCompatImageView ivIcon = view.findViewById(com.platform.view.R.id.iv_snack_icon);
    ivIcon.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            ivIcon.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            try {
                ivIcon.setImageResource(rootView.getContext().getApplicationInfo().icon);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    });
    AppCompatTextView tvMessage = view.findViewById(com.platform.view.R.id.tv_snack_message);
    tvMessage.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            tvMessage.setText(message);
            tvMessage.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        }
    });
    FrameLayout.LayoutParams param = (FrameLayout.LayoutParams) view.getLayoutParams();
    param.gravity = Gravity.CENTER;
    mSnackbar.setBackgroundTint(Color.TRANSPARENT);
    return mSnackbar;
}

具体更换Toast方案看自己使用场景

相关推荐
666xiaoniuzi2 小时前
深入理解 C 语言中的内存操作函数:memcpy、memmove、memset 和 memcmp
android·c语言·数据库
沐言人生6 小时前
Android10 Framework—Init进程-8.服务端属性文件创建和mmap映射
android
沐言人生7 小时前
Android10 Framework—Init进程-9.服务端属性值初始化
android·android studio·android jetpack
沐言人生7 小时前
Android10 Framework—Init进程-7.服务端属性安全上下文序列化
android·android studio·android jetpack
追光天使7 小时前
【Mac】和【安卓手机】 通过有线方式实现投屏
android·macos·智能手机·投屏·有线
小雨cc5566ru7 小时前
uniapp+Android智慧居家养老服务平台 0fjae微信小程序
android·微信小程序·uni-app
一切皆是定数8 小时前
Android车载——VehicleHal初始化(Android 11)
android·gitee
一切皆是定数8 小时前
Android车载——VehicleHal运行流程(Android 11)
android
problc8 小时前
Android 组件化利器:WMRouter 与 DRouter 的选择与实践
android·java
图王大胜9 小时前
Android SystemUI组件(11)SystemUIVisibility解读
android·framework·systemui·visibility