Android超实用的Toast提示框优化分享
程序员文章站
2024-03-07 09:19:20
前言
相信每位android开发者都用过toast,都知道是弹出消息的。类似于js里面的alert,c#里面的mesagebox。当然android里面也有dialog,...
前言
相信每位android开发者都用过toast
,都知道是弹出消息的。类似于js里面的alert
,c#里面的mesagebox
。当然android里面也有dialog
,dialog
是有焦点的,可与用户交互。而toast
是没有焦点的,时间到了自动消失,不能回应用户的交互,下面就跟大家分享下android中toast
提示框的优化方法。
先看下源码:
public class toast { public static final int length_short = 0; public static final int length_long = 1; /** * 构造一个空的toast。你必须在调动show()之前,线调用setview() * @param context 参数,application或者activity都可以 */ public toast(context context) { ... //获取系统内置的toast_y_offset常量值 mtn.my = context.getresources().getdimensionpixelsize( com.android.internal.r.dimen.toast_y_offset); mtn.mgravity = context.getresources().getinteger( com.android.internal.r.integer.config_toastdefaultgravity); } /** * 在指定的时长显示view视图 */ public void show() { //如果mnextview为空,即没有设置view if (mnextview == null) { throw new runtimeexception("setview must have been called"); } //通过系统服务,获取通知管理器。看来这是使用系统通知? inotificationmanager service = getservice(); string pkg = mcontext.getoppackagename(); tn tn = mtn; tn.mnextview = mnextview; try { service.enqueuetoast(pkg, tn, mduration); } catch (remoteexception e) { // empty } } /** * 关闭一个正在显示的toast, 或者取消一个未显示的toast. * 通常你不必调用它,在适当的时长后它会自动消失的。 */ public void cancel() { mtn.hide(); try { getservice().canceltoast(mcontext.getpackagename(), mtn); } catch (remoteexception e) { // empty } } /** * 设置toast显示的视图内容,不单单是黑色的界面,你可以自己决定显示什么 * @see #getview */ public void setview(view view) { mnextview = view; } /** * 设置时长,只能是下面这两个常量值,没什么卵用 * @see #length_short 2000毫秒 * @see #length_long 3500毫秒 */ public void setduration(@duration int duration) { mduration = duration; } /** * 设置view的外间距,不用多说. * * @param horizontalmargin the horizontal margin, in percentage of the * container width, between the container's edges and the * notification * @param verticalmargin the vertical margin, in percentage of the * container height, between the container's edges and the * notification */ public void setmargin(float horizontalmargin, float verticalmargin) { mtn.mhorizontalmargin = horizontalmargin; mtn.mverticalmargin = verticalmargin; } /** * 设置notification在屏幕中的方位,大家都知道.上中下左中右什么的都有 * @see android.view.gravity * @see #getgravity */ public void setgravity(int gravity, int xoffset, int yoffset) { mtn.mgravity = gravity; mtn.mx = xoffset; mtn.my = yoffset; } /** * 构造一个只包含一个textview的标准toast对象 * * @param context 通常是application或者activity对象 * @param text 用于显示的文本,可以是formatted text. * @param duration 显示时长. length_short或length_long * */ public static toast maketext(context context, charsequence text, @duration int duration) { toast result = new toast(context); layoutinflater inflate = (layoutinflater) context.getsystemservice(context.layout_inflater_service); //包含了一个默认的textview,这个textview的布局位置在 com.android.internal.r.layout.transient_notification,可以去查看下内容 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(text); result.mnextview = v; result.mduration = duration; return result; } /** * 更新通过maketext()方法创建出来的toast对象显示的文本内容 * @param s 待显示的新文本内容. */ public void settext(charsequence s) { if (mnextview == null) { throw new runtimeexception("this toast was not created with toast.maketext()"); } /** * 看来com.android.internal.r.layout.transient_notification布局里面的唯一的 * textview标签的id是r.id.message。拿到这个textview,设置新文本内容 */ textview tv = (textview) mnextview.findviewbyid(com.android.internal.r.id.message); if (tv == null) { throw new runtimeexception("this toast was not created with toast.maketext()"); } tv.settext(s); } static private inotificationmanager getservice() { if (sservice != null) { return sservice; } //获取远程的通知服务 sservice = inotificationmanager.stub.asinterface(servicemanager.getservice("notification")); return sservice; } //tn是一个瞬态通知的子类,里面包含显示和隐藏两个任务对象 private static class tn extends itransientnotification.stub { final runnable mshow = new runnable() { @override public void run() { handleshow(); } }; final runnable mhide = new runnable() { @override public void run() { handlehide(); // don't do this in handlehide() because it is also invoked by handleshow() mnextview = null; } }; //出现handler了哦 final handler mhandler = new handler(); /** * 调度handleshow任务到执行线程中 */ @override public void show() { if (locallogv) log.v(tag, "show: " + this); //handler发送异步任务了 mhandler.post(mshow); } /** * 同上 */ @override public void hide() { if (locallogv) log.v(tag, "hide: " + this); mhandler.post(mhide); } //... } }
通过上面的源码解读,了解到有远程通知,handler
异步任务等信息,不多说,自己看。
重点是toast的用法:
1、直接调用maketext静态方法即可,返回的是toast对象,最后别忘了调用show方法显示:
toast.maketext(context, text, duration).show();
或
toast toast = toast.maketext(context, text, duration); pre name="code" class="html"> toast.setview(view); toast.settext(s); toast.setgravity(gravity, xoffset, yoffset); toast.setduration(duration); toast.show();
2、还可以使用new的方式创建,别忘了setview()方法:
toast toast = new toast(); toast.setview(view); toast.settext(s); toast.setgravity(gravity, xoffset, yoffset); toast.setduration(duration); toast.show();
以上这些都不值得一提,很简单。
在开发过程中,有这样的需求:在项目总,我们偷懒,想连串toast
出多个变量的值或者其他任务,可在操作手机时直观可见。问题来了,弹出是无论我们的操作有多快,这些toast
内容都是一个跟着一个显示,没办法快进。哪怕我们玩完了,退出了app,它还在弹。怎么办?有没有办法让toast
的内容与我们的操作同步,快速反应?
public class t { private static toast toast; public static void show(context context, string msg) { if (toast == null) { toast = toast.maketext(context, msg, toast.length_short); } else { toast.settext(msg); } toast.show(); } }
单例模式,每次创建toast
都调用这个类的show
方法,toast
的生命周期从show
开始,到自己消失或者cancel
为止。如果正在显示,则修改显示的内容,你持有这个对象的引用,当然可以修改显示的内容了。若每次你都maketext
或者new
一个toast
对象,即每次通过handler
发送异步任务,调用远程通知服务显示通知,当然是排队等待显示了。
结束语
以上就是android中toast提示框优化的全部内容,希望对大家开发android能有所帮助,如果有大家有疑问可以留言交流。