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

相关推荐
QiLinkOS4 小时前
QiLink OS的失败数据共享平台的运作模式是否适用于所有行业?
android·开发语言·人工智能·算法·重构·开源
杉氧4 小时前
Framework 补完计划 (2):BufferQueue 与 SurfaceFlinger —— 像素的跨进程“接力赛”
android·架构·android jetpack
牢七4 小时前
RCE?复现成功
android
一化十4 小时前
Android16 自定义全局手势 任意界面依次点击屏幕四个角返回Home界面
android
三少爷的鞋6 小时前
Android 面试系列:Kotlin 协程的 delay 到底发生在哪个线程?
android
TechNomad17 小时前
Kotlin_Lambda编程详解
android·kotlin
熊猫_豆豆18 小时前
QT6 Android C++ 自制美观闹钟
android·c++·qt·闹钟
美狐美颜SDK开放平台18 小时前
Android/iOS直播APP平台开发中的视频美颜SDK优化技巧
android·ios·音视频·美颜sdk·第三方美颜sdk
聚美智数21 小时前
黄历查询-运势查询-国际法定节假日查询-API接口介绍
android·java·数据库
私人珍藏库1 天前
[Android] 一木百宝箱-万能百宝箱+抖音去水印等几百种功能
android·人工智能·app·软件·多功能