Toast分析——实现自己的Toast

uniapp 全局Toast 全局提示 兼容多端 基于uView 因为uniapp在小程序和App上不支持dom元素直接创建,网上一大堆解决办法都没卵用,故本人取巧解决了此问题。 首先需要uView,没有的自己百度。 //全局App.vue,加入全局参数 globalData: { toast:Object,//全局提示,必须在页面初始化 }, <template> <view> //建议使用全局导航栏,取消自带的导航栏,就只需要初始化一次,不然每个页面都要加入u-toast然后赋值初始化 <u-toast ref 阅读详情
    android 4.0以后,新增了一个功能:关闭某个应用发出的通知、Toast等。具体操作为:打开应用安装列表,找到要屏蔽的应用(长按通知,点击弹出的"应用信息",即可跳到应用信息界面),把允许推送消息(显示通知)取消即可。产品发现这个功能之后,果断要求屏蔽。能力有限,不知道如何破通知的屏蔽,自己实现一个Toast还是小case的~~

    Toast的实现很快想到两种方案,Dialog和浮窗(WindowManager)。Dialog怀疑代价可能比较大,因此没有去尝试,直接来看浮窗,最后发现Toast也是用浮窗实现的。决定用浮窗,就比较简单了,拿到WindowManager然后addView/removeView即可。既然决定重新实现,就弄的更好用一些——怎样调用更方便——最简单就直接提供个静态方法吧。然后就实现的细节了。相信有部分朋友跟我一样,对Toast的了解并不是很清楚,这里主要指Toast的现实策略,到现在都没有去细研究它是以一个什么样的策略显示的。下面是点点总结:

1、相同的消息,会取消之前的,最后一个会显示指定时间,不同的消息会串行显示(or 每个应用只能显示一定量的Toast,队列中有了则只更新显示时间);

2、显示时间只能使用指定的两种,自己设置了无效;

3、支持自定义显示内容;

4、主界面不在前台了,依然可以显示。在其他线程若使用则需要自己实现消息队列。

以上紧凭自己观察猜测,不一定对哈,错误地方欢迎指正。自己实现就不一定非得按照原始的样子了,满足产品要求,怎么爽,怎样美观就怎样写~~


    首先来看看Toast的使用:

Toast.makeText(getApplicationContext(), "hello world", Toast.LENGTH_LONG).show();
最简单的一个Toast调用,这个应该也是我们最常用的。

    接着,很自然的就会有各种其他的想法,比如自定义显示内容,不想每次都传入Context,现实在指定位置,控制显示时间,等等各种奇葩需求。看看上面这行代码,Toast.make(...)返回的是一个Toast对象,那么我们来看看拿到这个对象之后能做些什么:

mToast.setDuration(Toast.LENGTH_SHORT); // 显示时间
mToast.setText("hello world"); // may res id
mToast.setGravity(Gravity.LEFT|Gravity.TOP, 50, 300);
mToast.setMargin(0.5f, 0.5f);
mToast.setView(tvMsg); // 指定显示的view
mToast.cancel(); // 取消显示
mToast.show(); // 显示

非getXXX()方法就这些。除了常用的show/cancel外我们来看看剩下的几个方法是做什么的。

setText():这个就不用说了,显示的内容,支持字符串和字符串资源ID

setGravity():这个是显示的对齐方式,后面两个参数是针对前面对齐方式的x/y偏移量。比如,上面代码设置向屏幕的左上角对齐,并向右偏移50,向下偏移300

setMargin():margin,也就是外边距。比如我们通过Gravity设置显示在左上角,然后设置这两个值为0.5f,则Toast的左上角会现实在屏幕的中央

setView():设置显示内容视图,这个时候我们就可以自定义了。

好了,知道了这么多,我们就写个自定义的Toast出来:

private void bolgToast() {
	LinearLayout llMain = new LinearLayout(getApplicationContext());
	llMain.setOrientation(LinearLayout.VERTICAL);
	llMain.setBackgroundColor(Color.BLACK);
	llMain.setGravity(Gravity.CENTER);
	ImageView ivIcon = new ImageView(getApplicationContext());
	ivIcon.setImageResource(R.drawable.ic_launcher);
	llMain.addView(ivIcon);
	TextView tvMsg = new TextView(getApplicationContext());
	tvMsg.setText("hello word");
	tvMsg.setTextSize(18);
	llMain.addView(tvMsg);
	Toast mToast = new Toast(getApplicationContext());
	mToast.setView(llMain);
	mToast.show();
}
最后效果如下:



应该还行吧~~下面简单说几个问题:

1、有时候可能不知不觉在非主线程调用了Toast,这个时候系统可能会给你报这样一个错误:

08-09 00:01:36.353: E/AndroidRuntime(24817): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
这个错误很明显,可能需要我们自己去实现当前线程的消息系统。网上的很多例子告诉我们可以这样写:

new Thread(new Runnable() {
	
	@Override
	public void run() {
		Looper.prepare();
		Toast.makeText(getApplicationContext(), "hello ttdevs", Toast.LENGTH_LONG).show();
		Looper.loop(); // 不仅仅需要prepare,还需要这句,不然不报错但Toast也不出来
	}
}).start();

其实本人一直很好奇这样写的意义在哪里。当然你也可以这么写:

new Thread(new Runnable() {
	
	@Override
	public void run() {
		new Thread(new Runnable() {
		
			Handler mHandler = new Handler(Looper.getMainLooper()) {
				@Override
				public void dispatchMessage(Message msg) {
					Toast.makeText(getApplicationContext(), "hello ttdevs", Toast.LENGTH_LONG).show();
				}
			};
		
			@Override
			public void run() {
				mHandler.sendEmptyMessage(0);
			}
		}).start();
	}
}).start();
效果是一样的(activity中写的一段测试代码,你能理解为什么用了Thread的嵌套来模拟问题吗?(?))。

2、有的时候你也可能会遇到这样的问题:

08-09 00:17:28.053: E/AndroidRuntime(26441): Caused by: java.lang.RuntimeException: This Toast was not created with Toast.makeText()
我的测试代码是这样的:

Toast mToast = new Toast(getApplicationContext());
mToast.setText(String.valueOf(Math.random()));
mToast.show();
对于这个问题,我们只能老老实实的用Toast.makeText()来构造一个Toast了。具体原因我们之后会分析。

3、RuntimeException:setView must have been called , 这个问题常见于在调用show()之前调用过cancel()。是否还记得这个cancel方法呢?查看源码我们看到:

        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;
            }
        };
在执行完隐藏之后会将mNextView = null。

    下面我们来分析下Toast的源码(最新的4.4),其他版本比如2.2可能和这个版本有较大不同,大家可以自行分析。首先我们来看下最常用的makeText()方法:

    /**
     * Make a standard toast that just contains a text view.
     *
     * @param context  The context to use.  Usually your {@link android.app.Application}
     *                 or {@link android.app.Activity} object.
     * @param text     The text to show.  Can be formatted text.
     * @param duration How long to display the message.  Either {@link #LENGTH_SHORT} or
     *                 {@link #LENGTH_LONG}
     *
     */
    public static Toast makeText(Context context, CharSequence text, int duration) {
        Toast result = new Toast(context);

        LayoutInflater inflate = (LayoutInflater)
                context.getSystemService(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(text);
        
        result.mNextView = v;
        result.mDuration = duration;

        return result;
    }
这个方法是返回一个标准的仅仅带有一个TextView的Toast。先是通过Toast的默认构造方法创建一个Toast对象。然后给这个Toast设置view和显示时间。其中R.layout.transient_notification是一个简单线型布局里面嵌套个TextView,大家可以自行查看源码;然后就是设置显示时间,对于long和short这里面并不是一个时间值,而是一个0/1这种静态flag常量,这也就简单说明为什么我们传入的duration为时间的话无效的原因了。接下来我们在看Toast的构造方法:

    /**
     * Construct an empty Toast object.  You must call {@link #setView} before you
     * can call {@link #show}.
     *
     * @param context  The context to use.  Usually your {@link android.app.Application}
     *                 or {@link android.app.Activity} object.
     */
    public Toast(Context context) {
        mContext = context;
        mTN = new TN();
        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);
    }
关键部分还是创建一个TN对象,继续跟进:


上面是TN的结构和构造方法。这个构造方法还是比较简单的。修改WindowManager.LayoutParams的参数,如果你弄过浮窗,这里就比较简单了。比较好奇的的LayoutParams.TYOE_TOAST,竟然有这个type,然后立马就想到,屏蔽Toast是不是就根据这个Type,不过通过测试,发现不是。 最让我感觉五雷轰顶的还是这个注释:This should be changed to use a Dialog, with a Theme.Toast  defined that sets up the layout params appropriately.为什么会有这个注释呢?写了这个注释又为什么不用dialog来实现呢?做了下面这个尝试:


发现并没有Theme.Toast,不知道是不是系统内部的,不给用户使用。不过,这也说明,用dialog实现可能是没有问题的。好了,就到这吧,能力有限再继续往下跟就困难了。

    回到上面的Toast来看看我们常用的show()方法:

    /**
     * Show the view for the specified duration.
     */
    public void show() {
        if (mNextView == null) {
            throw new RuntimeException("setView must have been called");
        }

        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        TN tn = mTN;
        tn.mNextView = mNextView;

        try {
            service.enqueueToast(pkg, tn, mDuration);
        } catch (RemoteException e) {
            // Empty
        }
    }
关键部分跟不进去,暂时就不看了。值得注意的一点是这个RuntimeException:setView must have been called。如果我们遇到这个错误提示就应该知道是显示Toast的View为null。结合TN的代码,可能很自然的想到真正显示的时候应该是TN.show(),通过handler最终执行的是下面的方法:

        public void handleShow() {
            if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                    + " mNextView=" + mNextView);
            if (mView != mNextView) {
                // remove the old view if necessary
                handleHide();
                mView = mNextView;
                Context context = mView.getContext().getApplicationContext();
                if (context == null) {
                    context = mView.getContext();
                }
                mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
                // We can resolve the Gravity here by using the Locale for getting
                // the layout direction
                final Configuration config = mView.getContext().getResources().getConfiguration();
                final int gravity = Gravity.getAbsoluteGravity(mGravity, config.getLayoutDirection());
                mParams.gravity = gravity;
                if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
                    mParams.horizontalWeight = 1.0f;
                }
                if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
                    mParams.verticalWeight = 1.0f;
                }
                mParams.x = mX;
                mParams.y = mY;
                mParams.verticalMargin = mVerticalMargin;
                mParams.horizontalMargin = mHorizontalMargin;
                if (mView.getParent() != null) {
                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                    mWM.removeView(mView);
                }
                if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
                mWM.addView(mView, mParams);
                trySendAccessibilityEvent();
            }
        }
整个思路还是比较简答的,准备条件,最终调用WindowManager的addView方法将我们的View显示在界面上。handleHide()类似,将我们的View从界面上remove掉。值得注意的是hide的时候,我们的View会被置为null。
    最后,我们来总结下Toast的。首先,我们需要通过new Toast或者Toast.makeText的方式构造一个Toast对象,贮备好要所需数据。当执行show的时候,会将这些数据传递给Android的Notification系统,然后由其负责处理相应的逻辑并最终通过WindowManager显示在界面上。通过上面的分析我们也应该知道Toast和Notification用的同一个Notification系统。没有去仔细的分析各个版本在实现的上的差异,如果有问题大家可以去看对应的Toast源码来找具体的解决办法。下面提供两个参考:

1、http://blog.youkuaiyun.com/ameyume/article/details/7714491

2、http://www.imooo.com/yidongkaifa/android/1009042.htm

    最后我们来谈谈自己实现的Toast:通过一个show方法,将自己的Toast 加入一个消息队列中,然后循环取出消息队列中的内容显示。隐藏也是通过一个特殊的消息来完成。当消息队列达到一定大小,我们采取最简单的逻辑即清空队列来处理。另外作为一个全局的东西,我们需要初始化和回收,初始化建议在application中完成。

代码如下(BaseThread请到我的置顶的那篇文章中查看):

public class ToastUtil extends BaseThread {
	private static final int SHOW_TIME = 2000; // 显示时间
	private static final int QUEUE_SIZE = 120; // 队列大小
	private static final int QUEUE_SIZE_LIMIT = 100; // 限制队列大小
	private static final int FLAG_SHOW = 1000; // 显示
	private static final int FLAG_HIDE = 1001; // 隐藏
	private static final int FLAG_CLEAR = 1002; // 清理消息队列
	private static final String QUITMSG = "@bian_#feng_$market_%toast_&quit_*flag"; // 退出的标记

	private static BlockingQueue<String> mMsgQueue = new ArrayBlockingQueue<String>(QUEUE_SIZE); // 消息缓存队列

	private static ToastUtil mToast;

	private WindowManager mWindowManager;
	private WindowManager.LayoutParams mParams;
	private View toastView;
	private TextView tvAlert;

	@SuppressLint("InflateParams")
	private ToastUtil(Context context) {
		mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

		mParams = new WindowManager.LayoutParams();
		mParams.type = WindowManager.LayoutParams.TYPE_TOAST; //TYPE_SYSTEM_OVERLAY
		mParams.windowAnimations = android.R.style.Animation_Toast;
		mParams.format = PixelFormat.TRANSLUCENT;
		mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
		mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
		mParams.gravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
		mParams.alpha = 1f;// 透明度,0全透 ,1不透
		mParams.verticalMargin = 0.75f;
		mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

		toastView = LayoutInflater.from(context).inflate(R.layout.layout_toast, null);
		tvAlert = (TextView) toastView.findViewById(R.id.tvAlert);

		start();
	}

	/**
	 * 初始化消息显示
	 * 
	 * @param context
	 */
	public static void init(Context context) {
		if (null == mToast) {
			mToast = new ToastUtil(context);
		}
	}

	private Handler mHandler = new Handler(Looper.getMainLooper()) {

		public void handleMessage(android.os.Message msg) {
			int what = msg.what;
			switch (what) {
			case FLAG_SHOW:
				String str = msg.obj.toString();
				if (!TextUtils.isEmpty(str)) {
					showMsg(str);
				}
				break;
			case FLAG_HIDE:
				hideMsg();
				break;
			case FLAG_CLEAR:
				showMsg("操作异常,消息太多");
				break;

			default:
				break;
			}
		};
	};

	private void showMsg(String msg) {
		try {
			tvAlert.setText(msg);
			if (null == toastView.getParent()) {
				mWindowManager.addView(toastView, mParams);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void hideMsg() {
		try {
			if (null != toastView.getParent()) {
				mWindowManager.removeView(toastView);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 显示消息
	 * 
	 * @param msg
	 *            显示的内容
	 */
	public static void show(String msg) {
		try {
			mMsgQueue.put(msg); // block
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void show(Context context, int id) {
		try {
			mMsgQueue.put(context.getResources().getString(id)); // block
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 退出
	 */
	public static void eixt() {
		try {
			mMsgQueue.put(QUITMSG);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void execute() {
		try {
			String msgStr = mMsgQueue.take();
			
			if (QUITMSG.equals(msgStr)) {
				exitToast();
				return;
			}

			Message msg = mHandler.obtainMessage();
			if (null == msg) {
				msg = new Message();
			}
			msg.what = FLAG_SHOW;
			msg.obj = msgStr;
			mHandler.sendMessage(msg);

			Thread.sleep(SHOW_TIME);

			if (mMsgQueue.size() == 0) {
				mHandler.sendEmptyMessage(FLAG_HIDE);
			}

			if (mMsgQueue.size() > QUEUE_SIZE_LIMIT) {
				mMsgQueue.clear();

				mHandler.sendEmptyMessage(FLAG_CLEAR);
				Thread.sleep(SHOW_TIME);
				mHandler.sendEmptyMessage(FLAG_HIDE);
			}

			System.out.println(">>>>>" + mMsgQueue.size());
		} catch (Exception e) {
			e.printStackTrace();
			mHandler.sendEmptyMessage(FLAG_HIDE);
		}
	}

	/**
	 * 退出,清理内存
	 */
	private void exitToast() {
		try {
			hideMsg();

			quit();
			mMsgQueue.clear();
			mMsgQueue = null;
			mToast = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


uni-app封装的request请求 【代码】uni-app封装的request请求。 阅读详情

相关推荐

Toast的基本使用代码

Toast的基本使用代码,对应博客中2.1 Toast(吐司)的基本使用。

uniapp中的uni.$u.toast基本知识

在 uView 框架中,uni.$u.toast 是一个简单而有效的方法,用于在应用程序中显示消息提示

码农研究僧的博客 6192

vue教程之toast弹框全局调用示例详解

主要为大家详细介绍了vue教程之toast弹框全局调用示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

u-popup遮盖u-toast

u-popup遮盖u-toast

很菜,很菜,很菜... 4994

ESP-SR实战:从零搭建智能语音唤醒与命令识别系统

本文详细介绍了如何利用乐鑫ESP-SR框架,从零开始搭建一个完整的离线智能语音交互系统。内容涵盖硬件选型(推荐ESP32-S3与数字麦克风)、开发环境配置(ESP-IDF与ESP-ADF),并深入解析了AFE声学前端、WakeNet唤醒词检测和MultiNet命令词识别三大核心模块的工作原理与实战配置。通过具体的代码示例和调试技巧,指导开发者快速实现高识别率的语音唤醒与命令控制功能。

weixin_29161785的博客 302

AI辅助专利撰写实战:用Codex 30分钟生成发明专利初稿

这次我们来看一个用 Codex 从零开始撰写发明专利的实战项目。对于技术研发人员、产品经理或初创团队来说,专利申请是保护创新成果、构建技术壁垒的关键一步。然而,撰写一份高质量的专利申请书,尤其是权利要求书和说明书,往往需要专业的法律和技术语言,耗时耗力。这个项目演示了如何利用 AI 工具 Codex,在短时间内生成一份结构完整、逻辑清晰、具备授权潜力的专利申请文件初稿。 整个过程的核心不是让 AI 完全替代专利代理人,而是将其作为强大的“技术翻译”和“内容生成”助手。它能将你的技术构思、流程图、核心算法或产

weixin_32181267的博客 421

Toast分析——实现自己的Toast,toast分析实现

Toast分析——实现自己的Toast,toast分析实现 android 4.0以后,新增了一个功能:关闭某个应用发出的通知、Toast等。具体操作为:打开应用安装列表,找到要屏蔽的应用(长按通知,点击弹出的"应用信息",即可跳到应用信息界面),把允许推送消息(显示通知)取消即可。产品发现这个功能之后,果断要求屏蔽。能力有限,不知道如何破通知的屏蔽,自己实现一个Toast还是小case的~~ ...

weixin_37897683的博客 575

VMD-CNN-BiLSTM-Attention预测模型 —— 数学模型介绍&完整实例代码

想解决电力负荷预测中的非线性、非平稳难题?这篇博客介绍了一种创新混合模型,结合变分模态分解(VMD)和CNN-BiLSTM-Attention深度学习架构,实现超高精度预测! ✨ 核心亮点: ✅ VMD分解:有效分离复杂负荷信号,提取关键频率特征 ✅ 混合深度学习:CNN捕捉局部模式 + BiLSTM学习长时序依赖 + 注意力机制聚焦关键时段 ✅ 端到端优化:从数据预处理(滑动窗口、归一化)到模型训练(MSE损失+Adam优化),完整流程公开! ✅ 工业级评估:提供MSE、MAE、MAPE、R²多指标验证

qq_42924330的博客 1657

Toast实现原理分析

Toast2 // ...6 // ...7}Toast通过静态方法makeText来创建实例。Toast的显示和隐藏是通过来管理的。Toast的视图是通过来创建的。Toast的视图添加到了中,并且设置了特定的参数,如位置和透明度。Toast的显示时间是通过Handler来控制的。

VitorLiu的博客 626

【腾讯小龙虾WorkBuddy专栏04】一文搞懂WorkBuddy的「专家」和「专家团」

WorkBuddy专家与专家团:专业级AI协作解决方案 WorkBuddy的专家(Expert)与专家团(Expert Team)功能颠覆了通用AI的局限性,提供角色化、可交付的专业服务。 核心优势 专家:深度垂直领域的AI顾问,具备人设、方法论、工具链,如全栈开发专家能直接交付完整项目,而非代码片段。 专家团:多智能体协作,自动拆解复杂任务(如竞品分析、全栈开发)并分发给对应角色,并行执行后整合输出,效率提升显著。 使用场景 单专家:解决专业问题(如SQL优化、UI设计)。

AI人人懂 2038

RK3588 MPP,RGA,DRM,QT之RGA

RK3588多路视频采用RGA来进行混合成一帧

dreamliweiming的博客 4267

Android在子线程中显示Toast实现与源码分析

Android在子线程中显示Toast实现与源码分析

皖江的博客 1648

华为od 面试八股文_C++_02_含答案

华为od 面试八股文_C++_02_含答案

MISAYAONE的博客 3124

鸿蒙开发5.0案例分析:基于ArkUI实现类似Toast弹窗

使用@CustomDialog装饰器装饰自定义弹窗,在此装饰器内进行自定义内容(也就是弹框内容)、并创建构造器,与装饰器呼应相连。使用定时器,在页面的生命周期onPageShow中设置定时任务,页面显示时打开弹窗。可自定义弹窗位置,5.0规格,未设置alignment弹窗默认居中显示。可设置弹窗宽度、高度。gridCount弹窗宽度占栅格宽度的个数最大为4栅格宽度(400vp),API 12可通过width和height属性指定宽高。弹窗高度最大值:0.9 *(窗口高度 - 安全区域)

2501_91726121的博客 992

【系统分析师】2025年下半年真题:案例分析-答案及详解(回忆版)

Redis相比Memcached在电商高并发场景下具有显著优势:支持持久化(RDB/AOF)、丰富数据结构(如有序集合实现排行榜)、原生支持集群和哨兵模式(高可用性)。布隆过滤器通过位数组和哈希函数预先存储所有合法订单ID,当查询请求到达时快速拦截无效ID(如伪造ID),避免其穿透缓存直接冲击数据库,从而预防缓存击穿问题。

数据知道的博客 5998

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Android中的Toast源码分析和自定义Toast

我的主页 Demo下载地址 一、系统自带Toast的源码分析1. Toast的调用显示 学过Android的人都知道,弹出一个系统API吐司只需要一行代码,调用的是Toast对象的makeText()方法,方法里给一个上下文,显示的文字,和显示的时长,然后再调用show方法就能显示。Toast.makeText(this,"下载失败",Toast.LENGTH_SHORT).show();2. To

Pinger的博客 1631

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

鸿蒙常见问题分析三十九:Toast组件如何实现圆角与自定义样式

理解框架设计:原生Toast的“限制”是设计选择,不是缺陷。理解这一点,能帮助我们找到正确的扩展方向。 组件化思维:将Toast拆分为内容组件、管理器、配置选项,实现了关注点分离和高度复用。 完整生命周期:从显示、定时关闭、点击关闭到内存清理,考虑了完整的用户体验。 灵活性与规范:在提供最大灵活性的同时,通过样式常量等机制,确保团队内的使用一致性。

m0_59315734的博客 125

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Android Toast进阶——自定义Toast

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl B 斜体 Ctrl I 引用 Ctrl

小一的专栏 4133

Toast与Snackbar的那点事

我们的核心目标只是希望在用户关闭通知消息开关的情况下,能继续看到通知,所以我们使用了WindowManager添加自定义window的方式来替换Toast,但是在替换的过程中遇到了一些Toast的Crash异常,为了解决这些Crash,我们提出了使用自定义ToastHandler的方式来catch住异常,确保app正常运行。在方案推广上,为了能用更少的人力,更高的效率完成替换,我们使用了AspectJ的方案。

2501_90251165的博客 1260

Toast源码分析(Android 11)

基于Android R(11) ,targetSdkVersion 30源码分析 基本用法 普通Toast: Toast.makeText(this@MainActivity, "hello Toast!", Toast.LENGTH_SHORT).show() 自定义View的Toast: val toast = Toast(this@MainActivity) val view = Button(this@MainActivity) view.text = "custom toast!".

guangdeshishe的博客 1785

Toast源码分析

1, 概述 Toast是一种向用户快速展示少量信息的视图。当它显示时,它会浮在整个应用层的上面,并且不会获取到焦点。它的设计思想是能够向用户展示些信息,但又能尽量不显得唐突。本篇我们来研读一下Toast的源码,并探明它的显示及隐藏机制。 2 实现 从Toast的最简单调用开始,它的调用代码是: Toast.makeText(context,"Show toast",Toast.LENGT

Jack的博客 619
上一篇: andriod API文档打不开 google打不开
下一篇: android Notification分析——你可能遇到的各种问题
ttdevs
博客等级 码龄15年 388粉丝 91原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值