安卓toast toast弹窗的用法

起源

targetSdkVersion为30时运行在Android 11的小米10手机上,调用ToastUtil时闪退报错:

null不能转换为非null类型Android . widget . linear layout

看看已知的条件:

targetSdkVersion 30Android 11小米10

文末附上一份Android 11适配手册。

定位问题

好的,如果遇到问题,快速定位。我重新包装了原来的祝酒词,ToastUtil。

所以我很快找到了问题所在。

私趣create toast(msg:String){ if(toast = = null){ toast = toast . make text(yutils . getapp()。applicationContext,msg,Toast。LENGTH_SHORT) } else { toast!!。setText(msg)} val linear layout = toast!!。view as linear layout val message TextView = linear layout . get child at(0)as TextView message TextView . textsize = 15f toast!!。show() }

没错,就是这句话被改造了:

val linearLayout = toast!!。以线性布局方式查看

代码也比较简单。获得视图后,我只需设置字体大小。

为什么要写这个?看下面的源代码分析(很简单)。

源码解析

我们一般的称呼是这样写的:

Toast.makeText(上下文,味精,吐司。LENGTH_SHORT)。show()

一行代码,也很容易找到重点——make text,没错,接下来的分析就是从这里开始的。

compileSdkVersion 30之前

以compileSdkVersion 28为例,makeText源代码:

public static Toast make text(@ NonNull Context Context,@Nullable Looper looper,@NonNull CharSequence text,@ Duration int Duration){ Toast result = new Toast(Context,Looper);layoutinflate inflate =(layoutinflate)Context . getsystem service(Context。LAYOUT _ INFLATER _ SERVICE);view v = inflate . inflate(com . Android . internal . r . layout . transient _ notification,null);TextView TV =(TextView)v . findviewbyid(com . Android . internal . r . id . message);tv.setText(文本);result . mnext view = v;result.mDuration =持续时间;返回结果;}

这几行代码的关键点是什么?这是:

view v = inflate . inflate(com . Android . internal . r . layout . transient _ notification,null);

参考布局来显示信息。

这种布局也很简单:

& ltlinear layout xmlns:Android = & # 34;http://schemas.android.com/apk/res/android"安卓:layout _ width = & # 34match _ parent & # 34Android:layout _ height = & # 34;match _ parent & # 34Android:orientation = & # 34;垂直& # 34;安卓:背景= & # 34;?Android:attr/toast frame background & # 34;& gt& ltTextView Android:id = & # 34;@ Android:id/message & # 34;Android:layout _ width = & # 34;wrap _ content & # 34Android:layout _ height = & # 34;wrap _ content & # 34Android:layout _ weight = & # 34;1"Android:layout _ marginHorizontal = & # 34;24dp & # 34Android:layout _ margin vertical = & # 34;15dp & # 34Android:layout _ grity = & # 34;居中_水平& # 34;Android:text appearance = & # 34;@style/TextAppearance。敬酒& # 34;Android:text color = & # 34;@ color/primary _ text _ default _ material _ light & # 34;/& gt;& lt/linear layout & gt;

根布局LinearLayout和TextView显示文本。

这就是为什么我们得到了之前报告错误的这行代码:

val linearLayout = toast!!。以线性布局方式查看

现在看来,并没有什么不妥。其实在Android11下运行真的没问题。

SetView和getView也没问题。

/** *设置要显示的视图。* @ see # getView */public void set View(View View){ mnext View = View;} /** *返回视图。* @ see # set View */public View getView(){ return mnext View;}

作者:yechaoa

compileSdkVersion 30之后

重点是,源代码在compileSdkVersion 30之后有变化。

或者直接看关键makeText:

public static Toast make TEXT(@ NonNull Context Context,@Nullable Looper looper,@NonNull CharSequence text,@ Duration int Duration){ if(compatibility . is CHANGE enabled(CHANGE _ TEXT _ TOASTS _ IN _ THE _ SYSTEM)){ Toast result = new Toast(Context,Looper);result.mText = textresult.mDuration =持续时间;返回结果;} else { Toast result = new Toast(上下文,looper);view v = toast presenter . gettexttoastview(context,text);result . mnext view = v;result.mDuration =持续时间;返回结果;} }

嗯?获取视图的方式发生了变化。这曾经是膨胀的方式,但现在是了

view v = toast presenter . gettexttoastview(context,text);

好了,继续看toastpresenter。gettexttoastview

公共类ToastPresenter {…@ visible for testing public static final int TEXT _ TOAST _ LAYOUT = r . LAYOUT . transient _ notification;/** *返回消息{@code text}的默认文本提示视图。*/公共静态视图getTextToastView(Context Context,char sequence text){ View View View = layoutinflater . from(Context)。inflate(TEXT_TOAST_LAYOUT,null);TextView TextView = view . findviewbyid(com . Android . internal . r . id . message);textView.setText(文本);返回视图;} }

这里是不是有点眼熟?没错,和compileSdkVersion 28中的源代码差不多,但是布局变成了常量,有了注解@VisibleForTesting,但是xml代码还是一样的。

而setView和getView也是弃用的。

/** *设置要显示的视图。* * @ see # getView * @已弃用的自定义toast视图已弃用。应用程序可以使用* {@link #makeText(Context,CharSequence,int)}方法创建标准文本toast,或者使用* & lta href = & # 34{ @ docRoot } reference/com/Google/Android/material/snack bar/snack bar & # 34;& gtSnackbar & lt/a & gt;*在前台时。从Android {@link Build开始。VERSION_CODES#R},针对API级别的应用程序{ @ link Build。后台*中的VERSION_CODES#R}或更高版本将不会显示自定义toast视图。*/@已弃用的public void set View(View View){ mnext View = View;} /** *返回视图。* * & ltp & gt用{@link #Toast(Context)}构造的祝酒词没有& # 39;用非{@code null}视图调用的{@link #setView(View)} *将在此返回{@code null}。* * & ltp & gt从Android {@link Build开始。VERSION_CODES#R},在针对API级别{ @ link * Build }的应用中。VERSION_CODES#R}或更高版本,用{@link #makeText(Context,* CharSequence,int)}或其变体构造的toasts也将在此返回{@code null},除非它们用非{@code null}视图调用了* {@link #setView(View)}。如果您想在显示或隐藏* toast时得到通知,请使用{@link #addCallback(Callback)}。* * @ see # setView * @已弃用的自定义toast视图已弃用。应用程序可以使用* {@link #makeText(Context,CharSequence,int)}方法创建标准文本toast,或者使用* & lta href = & # 34{ @ docRoot } reference/com/Google/Android/material/snack bar/snack bar & # 34;& gtSnackbar & lt/a & gt;*在前台时。从Android {@link Build开始。VERSION_CODES#R},针对API级别的应用程序{ @ link Build。后台*中的VERSION_CODES#R}或更高版本将不会显示自定义toast视图。*/@ Deprecated @ Nullable public View getView(){ return mnex View;}

直接看笔记的要点:

@已弃用的自定义toast视图已弃用。应用程序可以使用{@link #makeText(Context,CharSequence,int)}方法创建标准文本toast,或者使用& lta href = & # 34{ @ docRoot } reference/com/Google/Android/material/snack bar/snack bar & # 34;& gtSnackbar & lt/a & gt;当在前景中时。从Android {@link Build开始。VERSION_CODES#R},appstargeting API级别{@link Build。后台中的VERSION_CODES#R}或更高版本将不显示自定义toast视图。

自定义toast视图toast已被否决。您可以创建标准的ToastView或使用Snackbar。从Android R开始,不再显示自定位吐司视图。

Android R也是Android11。具体版本的对应关系见。

在座的一些同学可能有一些想法。既然getView已经被放弃了,我能通过ToastPresenter得到它吗?GetTextToastView像一个系统?可惜行不通。ToastPresenter是@hide。。

适配方案

综上所述,适应计划也是明确的。

方案一

使用标准吐司

吐司。maketext(上下文、消息、吐司。length _ short)。Show () Scheme 2使用Snackbar。

Snackbar类似于吐司。了解更多相关信息。

Snackbar.make(查看,& # 34;行程已添加& # 34;,Snackbar。LENGTH_SHORT)。show()方案3没有使用系统的toast,但是可以借鉴来写自定义视图。

总体思路:

初始化引用自定义布局编写一些公开的set、get属性加上进入进出动画开始/结束显示倒计时

等空再补这个。。

Android 11开发手册

Android 11开发者手册

最后

写作不容易。如果对你有用,请给我点个赞。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论