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方案看自己使用场景

相关推荐
峥嵘life10 小时前
Android16 【CTS】CtsWindowManagerDeviceAnimations存在fail项
android·linux·学习
阿拉斯攀登11 小时前
第 7 篇 安卓驱动开发的灵魂:字符设备驱动框架,从原理到最简实战
android·驱动开发·rk3568·嵌入式驱动·安卓驱动
阿拉斯攀登11 小时前
第 1 篇 入坑不亏!瑞芯微 RK 平台 + 安卓驱动开发,小白全维度扫盲
android·驱动开发·rk3568·嵌入式驱动
Android系统攻城狮11 小时前
Android tinyalsa深度解析之pcm_params_get调用流程与实战(一百六十二)
android·pcm·tinyalsa·android hal·audio hal
zh路西法12 小时前
【C语言简明教程提纲】(四):结构体与文件定义和操作
android·c语言·redis
常利兵12 小时前
Jetpack Compose 1.8 新特性来袭,打造丝滑开发体验
android
牢七12 小时前
百家cms 审计 未完成
android·ide·android studio
hjxu201612 小时前
【 MySQL 速记5】插入
android·数据库·mysql
aq553560015 小时前
MySQL-触发器(TRIGGER)
android·数据库·mysql
一起搞IT吧16 小时前
Android功耗系列专题理论之十六:功耗不同阶段&不同模块分析说明
android·c++·智能手机·性能优化