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

相关推荐
Android-Flutter20 小时前
Compose 管理状态 详解
android·compose
缓慢更新21 小时前
审批的加签与会签:多人意见怎么合
android·java·数据库·低代码·rxjava
我怀里的猫1 天前
android-activity-launch-sequence
android
YB13751 天前
Jetpack Compose 动画rememberInfiniteTransition
android
baidu_247438611 天前
Android 自定义竖直的虚线
android
传奇开心果编程1 天前
【Jetpack Compose娓娓道来】 第25课:ViewModel就是UI界面的大脑
android·kotlin·移动开发·jetpack compose·编程语言理论·编程框架·声明式ui
马立杰1 天前
PHP 未授权 RCE 应急响应:CVE-2026-109618 CVE-2026-109619 排查与加固实战
android·开发语言·php
NamoAmitabha1281 天前
安装“编译器环境”(Android Studio)--deepseek--Cocos --Creator3.8.8
android·ide·android studio
聚美智数1 天前
文档转换 API‑文档转 PDF‑PDF 转文档‑异步文档处理‑文件格式迁移‑转换结果回调推送 API 接口介绍
android·java·pdf
booboosui1 天前
Android 上的无人回合:只放开 2 类工具,宁可空手
android