2

❤️Android 快别用Toast了,来试试Snackbar❤️

 2 years ago
source link: http://www.androidchina.net/12089.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

❤️Android 快别用Toast了,来试试Snackbar❤️ – Android开发中文站

你的位置:Android开发中文站 > Android开发 > 新手入门 > 简单控件 > ❤️Android 快别用Toast了,来试试Snackbar❤️

Toast提示默认显示在界面底部,使用Toast.setGravity()将提示显示在中间,如下:

        Toast toast = Toast.makeText(this, str, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();

运行在在Android 12上无法显示,查看Logcat提示如下:

Toast: setGravity() shouldn't be called on text toasts, the values won't be used

意思就是:你不能使用toast调用setGravity,调用无效。哎呀,看给牛气的,咱看看源码找找原因

Toast.setGravity()

    /**
     * 设置Toast出现在屏幕上的位置。
     *
     * 警告:从 Android R 开始,对于面向 API 级别 R 或更高级别的应用程序,此方法在文本 toast 上调用时无效。
     */
    public void setGravity(int gravity, int xOffset, int yOffset) {
        if (isSystemRenderedTextToast()) {
            Log.e(TAG, "setGravity() shouldn't be called on text toasts, the values won't be used");
        }
        mTN.mGravity = gravity;
        mTN.mX = xOffset;
        mTN.mY = yOffset;
    }

妥了,人家就告诉你了 版本>=Android R(30),调用该方法无效。无效就无效呗,还不给显示了,过分。

Logcat的提示居然是在这里提示的,来都来了,咱们看看isSystemRenderedTextToast()方法。

Toast.isSystemRenderedTextToast()

    /**
     *Text Toast 将由 SystemUI 呈现,而不是在应用程序内呈现,因此应用程序无法绕过后台自定义 Toast 限制。
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
    private static final long CHANGE_TEXT_TOASTS_IN_THE_SYSTEM = 147798919L;

    private boolean isSystemRenderedTextToast() {
        return Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM) && mNextView == null;
    }

重点了。Text Toast 将由 SystemUI 呈现,而不是在应用程序内呈现。

清晰明了,可以这样玩,但是你级别不够,不给你玩。

事情整明白了,再想想解决解决方案。他说了Text Toast 将由 SystemUI 呈现,那我不用 Text 不就行了。

Toast 提供的方法

先看看Tast提供的方法:

有这几个方法。咱们实践一下。保险起见看看源码

Toast.setView() 源码

    /**
     * 设置显示的View
     * @deprecated 自定义 Toast 视图已弃用。 应用程序可以使用 makeText 方法创建标准文本 toast,
     * 或使用 Snackbar
     */
    @Deprecated
    public void setView(View view) {
        mNextView = view;
    }

这个更狠,直接弃用。

  • 要么老老实实的用默认的Toast。
  • 要么使用 Snackbar。

Snackbar

Snackbar 就是一个类似Toast的快速弹出消息提示的控件(我是刚知道,哈哈)。

与Toast相比:

  • 一次只能显示一个
  • 与用户交互
    • 在右侧设置按钮来添加事件,根据 Material Design 的设计原则,只显示 1 个按钮 (添加多个,以最后的为准)
  • 提供Snackbar显示和关闭的监听事件
    • BaseTransientBottomBar.addCallback(BaseCallback)
    showMessage(findViewById(android.R.id.content), str, Snackbar.LENGTH_INDEFINITE);

    public static void showMessage(View view, String str, int length) {
        Snackbar snackbar = Snackbar.make(view, str, length);

        View snackbarView = snackbar.getView();
        //设置布局居中
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(snackbarView.getLayoutParams().width, snackbarView.getLayoutParams().height);
        params.gravity = Gravity.CENTER;
        snackbarView.setLayoutParams(params);
        //文字居中
        TextView message = (TextView) snackbarView.findViewById(R.id.snackbar_text);
        //View.setTextAlignment需要SDK>=17
        message.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
        message.setGravity(Gravity.CENTER);
        message.setMaxLines(1);
        snackbar.addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
            @Override
            public void onDismissed(Snackbar transientBottomBar, int event) {
                super.onDismissed(transientBottomBar, event);
                //Snackbar关闭
            }

            @Override
            public void onShown(Snackbar transientBottomBar) {
                super.onShown(transientBottomBar);
                //Snackbar显示
            }
        });
        snackbar.setAction("取消", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //显示一个默认的Snackbar。
                Snackbar.make(view, "我先走", BaseTransientBottomBar.LENGTH_LONG).show();
            }
        });
        snackbar.show();
    }

Snackbar.make的三个参数:

  • View:从View中找出当前窗口最外层视图,然后在其底部显示。
  • 第二个参数(text)
    • CharSequence
    • StringRes
  • duration(显示时长)
    • Snackbar.LENGTH_INDEFINITE 从 show()开始显示,直到它被关闭或显示另一个 Snackbar
    • Snackbar.LENGTH_SHORT 短时间
    • Snackbar.LENGTH_LONG 长时间
    • 自定义持续时间 以毫秒为单位

Android 12

Android 5.1

如果觉得设置麻烦可以看看下面这边文章,然后整合一套适合自己的。

一行代码搞定Snackbar

我是开发者小程序上线啦,欢迎使用!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK