Android中如何自己定义吐司(Toast)

Android系统里面有个东西很好用,也很常用,那就是Toast,但是长期使用也会发现,Toast有他的不足之处:形式单一,只有文字,风格不变等等,那么要如何自定义一个Toast呢,我们可以先从分析Android定义Toast的代码着手:

Toast的makeText方法

这里实际上Android所做的工作是将Toast显示的文本和持续时间设置了一下,然后返回了Toast对象,用以执行show()方法。这里核心的地方是要弄明白

这一句Android做了一些什么工作,下面我们继续看:

这里实际上是new 了一个TN()对象,然后对TN对象设置了一些关于位置和偏移的参数。那么那个TN是何方神圣呢?我们可以继续往下看:

我们可以发现,TN的构造函数里面执行了一个handleShow的方法

我们可以发现handleshow这个方法执行了一大堆的语句,但是实际上我们需要重点关注的只有一句,也就是上面选中的一句:mWM.addView(mView,mParams);

实际上这个mWM是一个WindowManager,mView是要显示的组件的view,而mParams应该是参数的设置一类,但是具体是何方神圣呢?我们可以在Toast类中找到一个成员变量

我们发现mParams实际上是WindowManager的一个布局参数。但是如果单从handleShow方法来看mParams的设置感觉还是太乱,我们可以在Toast中找到下面这一段

在这里我们可以比较清楚看到mParams的一部分主要参数设置,其中包含了长宽都是wrap_content,然后是半透明的(TransLucent),然后还设置了一个动画效果(Animation_Toast),和一个标题(setTitle("Toast"))最后设置了Toast一些标识比如让屏幕亮起,不可触摸,不可获取焦点等。

到这里,我们基本上清楚了Toast是如何显示出来的,核心的在于使用一个WindowManager的addView方法,将要显示的view和参数mParams传进来,但是在此之前还需要设置mParams的一些参数;

那么这里是显示,Toast是如何让显示消失的呢?我们可以在handleShow方法下面找到一个handHide的方法

同样核心语句也是选中的一句,mWM.removeView(mView),这样就让Toast消失掉了

那么有了上面的一些分析,我们不难写出我们自己的Toast类,里面提供一些静态方法,让我们来自己定义Toast的显示风格和显示内容,也可以控制Toast的显示开始和结束的时机。

下面的自定义Toast类,提供了几种形式的show方法,可以像传统Toast一样,传入文本来显示一个testview,也可以完全自己定义传入view对象和mParams参数,这样可以定义出了一个完全自己定义的Toast

package com.alexchen.mobilesafeexercise.ui;

import android.content.Context;
import android.graphics.PixelFormat;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 自定义吐司
 *
 * @author Alex
 *
 */
public class MyToast {
	/**
	 * 窗体管理者
	 */
	private static WindowManager wm;
	private static WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
	private static View mView;
	private static TextView tv;

	/**
	 * 显示自定义吐司
	 *
	 * @param info
	 * @param context
	 */
	public static void show(String message, Context context) {
		wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		tv = new TextView(context);
		tv.setText(message);
		tv.setTextSize(20);
		// 原来TN所做的工作
		WindowManager.LayoutParams params = mParams;
		params.height = WindowManager.LayoutParams.WRAP_CONTENT;
		params.width = WindowManager.LayoutParams.WRAP_CONTENT;
		params.format = PixelFormat.TRANSLUCENT;
		params.type = WindowManager.LayoutParams.TYPE_TOAST;
		params.setTitle("Toast");
		params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
				| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
				| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

		wm.addView(tv, params);

	}

	/**
	 * 自定义文本吐司的显示方法,这个方法提供了更多自定义的内容,比如textview可以应用一个传入的style的id
	 *
	 * @param message
	 * @param context
	 * @param textViewResid
	 * @param params
	 */
	public static void show(String message, Context context, int textViewResid,
			WindowManager.LayoutParams params) {
		wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		tv = new TextView(context);
		// 多加了一个风格
		tv.setTextAppearance(context, textViewResid);
		// 原来TN所做的工作
		// WindowManager.LayoutParams params = mParams;
		// params.height = WindowManager.LayoutParams.WRAP_CONTENT;
		// params.width = WindowManager.LayoutParams.WRAP_CONTENT;
		// params.format = PixelFormat.TRANSLUCENT;
		// params.type = WindowManager.LayoutParams.TYPE_TOAST;
		// params.setTitle("Toast");
		// params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
		// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
		// | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

		wm.addView(tv, params);
	}

	/**
	 * 更多自定义的形式,可以直接传入任一个自己定义好的view,自己设置wm的参数
	 *
	 * @param view
	 * @param context
	 * @param params
	 *            WindowManager.LayoutParams类型的参数, WindowManager.LayoutParams
	 *            mParams = new WindowManager.LayoutParams(); params.height =
	 *            WindowManager.LayoutParams.WRAP_CONTENT; params.width =
	 *            WindowManager.LayoutParams.WRAP_CONTENT; params.format =
	 *            PixelFormat.TRANSLUCENT; params.type =
	 *            WindowManager.LayoutParams.TYPE_TOAST;
	 *            params.setTitle("Toast"); params.flags =
	 *            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
	 *            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
	 *            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
	 */
	public static void show(View view, Context context,
			WindowManager.LayoutParams params) {
		wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		MyToast.mView = view;
		wm.addView(mView, params);

	}

	/**
	 * 隐藏自定义吐司 这里一定要记得判空一下,因为平时没有打电话时,这两个量应该都是空的
	 */
	public static void hide() {
		if (wm != null) {
			if (tv != null) {

				wm.removeView(tv);

				tv = null;
			}
			if (mView != null) {

				wm.removeView(mView);

				mView = null;
			}
			if (tv == null && mView == null) {
				wm = null;
			}

		}
	}

}
时间: 2024-12-11 01:20:23

Android中如何自己定义吐司(Toast)的相关文章

Android中通过反射来设置Toast的显示时间

这个Toast的显示在Android中的用途还是非常大的,同一时候我们也知道toast显示的时间是不可控的.我们仅仅能改动他的显示样式和显示的位置,尽管他提供了一个显示时间的设置方法.可是那是没有效果的(后面会说到).他有两个静态的常量Toast.SHORT和Toast.LONG,这个在后面我会在源码中看到这个两个时间事实上是2.5s和3s. 那么我们假设真想控制toast的显示时间该怎么办呢?真的是无计可施了吗?天无绝人之路,并且Linux之父以前说过:遇到问题就去看那个操蛋的源码吧.!以下就

【Android】Android中AsyncTask的定义和使用方法

AsyncTask介绍 Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理. 首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的. Android为了降低这个开发难度,提供了AsyncTask.AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务. AsyncTask直接继承于Object类,位置为android.os.AsyncTask.要使

Android中使用dimen定义尺寸(转)

(转自:http://blog.csdn.net/yuzhiboyi/article/details/7696174) 最近,遇到了一种定义尺寸的方法,类似于C里面的宏定义一样,其实以前已经见过了这种使用方式,今天有时间就记录一下方便以后使用.下面来介绍一下: 尺寸资源XML文件的使用       下面还是通过一个实例来演示尺寸资源的用法.该实例在布局文件中添加一个TextView和一个Button,分别使用尺寸资源文件来定义它们的宽和高.        在工程的res\values\目录下创建

Android中为窗口定义主题

在res/values/styles文件夹中定义如下: 1 <style name="myTheme"> 2 <item name="android:windowNoTitle">true</item> 3 <item name="android:windowFullscreen">true</item> 4 <item name="android:windowBackg

Android中怎样做到自己定义的广播仅仅能有指定的app接收

今天没吊事.又去面试了,详细哪家公司就不说了,由于我在之前的blog中注明了那些家公司的名字,结果人家给我私信说我泄露他们的题目.好吧,我错了... 事实上当我们已经在工作的时候.我们能够在空暇的时间去面一面,由于面试有非常多优点的: 第一点:你知道这个公司的详细地址了,以后和朋友说的时候也是有话题的 第二点:这点非常重要.看看其它公司的面试题(如今有的公司还在採用笔试题这个环节.真心无语了.题目全是从网上找的,非常没有意思.所以我仅仅要见到有笔试题的一律pass,个人感觉面到如今,阿里和滴滴还

android中SELINUX规则分析和语法简介

############################################# 本文为极度寒冰原创,转载请注明出处 ############################################# 1. SELINUX是可以理解为一种android上面的安全机制,是有美国国家安全局和一些公司设计的一个针对linux的安全加强系统 我们可以通过配置SELINUX的相关policy,来定制自己的手机的一些权限,比如,我们可以完全让root用户没有任何的权限和user一样 2.

Android学习笔记二十之Toast吐司、Notification通知、PopupWindow弹出窗

Android学习笔记二十之Toast吐司.Notification通知.PopupWindow弹出窗 Toast吐司 Toast吐司是我们经常用到的一个控件,Toast是AndroidOS用来显示消息的一种机制,它与Dialog不同,Toast不会获取到焦点,通常显示一段时间之后就会自动消失,下面我们来介绍Toast的几种常用方式: 第一种,默认显示方式,也是最常用的方式: Toast.makeText(MainActivity.this, "这是默认的显示方式", Toast.LE

Android中土司(Toast)的使用

 Android中Toast的使用 什么是土司(Toast)? Toast是Android系统提供的一种非常好的提示方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消失,并且不会占用任何的屏幕空间. 下面我们通过代码来体验一下土司在Android中的使用 1 import android.app.Activity; 2 import android.content.Intent; 3 import android.os.Bundle; 4 import androi

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr