Snackbar 制作Toast遇到遮挡处理
为什么要用Snackbar替代Toast
如果你的应用程序目标是Android 12(API级别31)或更高版本,其Toast仅限于两行文本,并在文本旁边显示应用程序图标。请注意,此文本的行长度因屏幕大小而异,因此最好使文本尽可能短。
如果你的应用程序在前台,可以考虑使用Snackbar而不是Toast。Snackbar包括用户可操作的选项,可以提供更好的应用程序体验。
如果你的应用程序在后台,并且你希望用户采取一些行动,请使用Notification。
Snackbar局限性在于依附view,如何出现dialog或者popwindow等遮挡弹框将会被遮盖在后面。官方提的Notification可以作为后台弹窗,通常顶部弹出,展示效果和Toast存在着差异。另一种是将Snackbar制作成强行显示在应用最上方,需要借助WindowManager,还需要运行时权限申请。
Dialog 辅助 Snackbar制作不被遮挡的Snackbar
- 定义一个全屏透明的Dialog作为snackbar的容器窗口
- 给Dialog做一个延迟取消,时常和snackbar长短时长等同
- 控制窗口透明度,两窗口叠加时透明度会受到影响
- 页面销毁时要跳出方法不让重新创建
- Dialog受制于actvity,无法跨页面显示
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);
}
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方案看自己使用场景
网友评论