欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于Toast的一些常见操作

程序员文章站 2022-06-11 22:13:57
...

创建一个单例的Toast

使用场景

Toast也被称为吐司,比如说现在有两个地方弹一个吐司,当用户点击了A地方的时候吐司之后,又马上切换到B地方吐司,如果是没有使用单例的话,那么当弹起第一个吐司的时候,时间就会有2-3S的间隔才会弹出第二个吐司.那么给用户的体验就会非常不好.

默认的Toast写法

//如果是使用studio的话,可以打Toast就可以快速的写出这行代码,记得T必须是要大写,否则无法弹出对应的选项
Toast.makeText(MainActivity.this, "这是默认效果的Toast",  Toast.LENGTH_LONG).show();

单例Toast:

public class ToastUtil {
    /**
     * 第一次弹吐司的string
     */
    private static String oldMsg;
    protected static Toast toast = null;
    /**
     * 第一次弹吐司的时间
     */
    private static long oneTime = 0;
    /**
     * 再次弹吐司的时间
     */
    private static long twoTime = 0;

    public static void showToast(Context context, String s) {
        if (toast == null) {
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
            toast.show();
            oneTime = System.currentTimeMillis();//当前系统的时间
        } else {
            twoTime = System.currentTimeMillis();//再次获取系统的时间
            //判断传入的string是否与之前传入的string相同
            if (s.equals(oldMsg)) {
            //判断两次获取的当前系统时间是否超过默认的吐司时间,超过就再次吐司,否则就不再吐司
                if (twoTime - oneTime > Toast.LENGTH_SHORT) {
                    toast.show();
                }
            } else {
                oldMsg = s;
                toast.setText(s);
                toast.show();
            }
        }
        oneTime = twoTime;
    }

    public static void showToast(Context context, int resId) {
        showToast(context, context.getString(resId));
    }

}

表面上看没什么问题,但是在真实运用过程中,就会出现内存泄漏的问题。原因也很简单,当弹出一个toast的时候,当前页面关闭,但是toast还是引用了context。导致无法GC。所以应该将context变成context.getApplicationContext()。

最终的代码:

public class ToastUtil {
    /**
     * 第一次弹吐司的string
     */
    private static String oldMsg;
    protected static Toast toast = null;
    /**
     * 第一次弹吐司的时间
     */
    private static long oneTime = 0;
    /**
     * 再次弹吐司的时间
     */
    private static long twoTime = 0;

    public static void showToast(Context context, String s) {
        if (toast == null) {
            toast = Toast.makeText(context.getApplicationContext(), s, Toast.LENGTH_LONG);
            toast.show();
            oneTime = System.currentTimeMillis();//当前系统的时间
        } else {
            twoTime = System.currentTimeMillis();//再次获取系统的时间
            if (s.equals(oldMsg)) {//判断两次的string是否相同
                if (twoTime - oneTime > Toast.LENGTH_LONG) {//判断两次获取的当前系统时间是否超过默认的吐司时间,超过就再次吐司,否则就不再吐司
                    toast.show();
                }
            } else {
                oldMsg = s;
                toast.setText(s);
                toast.show();
            }
        }
        oneTime = twoTime;
    }
public static void showToast(Context context, int resId) {
        showToast(context, context.getString(resId));
    }

  }

自定义Toast

自定义显示位置

Toast toast = Toast.makeText(MainActivity.this, "这是自定义位置的Toast", Toast.LENGTH_LONG);
                //设置Toast在屏幕上显示的位置
                toast.setGravity(Gravity.CENTER, 20,80);
                toast.show();

自定义显示图标:

Toast toast = Toast.makeText(MainActivity.this, "这是带图片的Toast", Toast.LENGTH_LONG);
              //创建一个子布局用于自定义Toast的内容
              LinearLayout toastView = (LinearLayout) toast.getView();
              //在这个子布局中定义一个ImageView用于添加Toast显示的图片
              ImageView  iv= new ImageView(MainActivity.this);
              iv.setImageResource(R.drawable.p3);
              //把ImageView添加到子布局当中
              toastView.addView(iv, 0);
              toast.show();

完全自定义的:

//创建一个布局,用于承载Toast中的内容
                LayoutInflater inflater = getLayoutInflater();
                View view = inflater.inflate(R.layout.cell, null);
                //Toast中的内容之一ImageView用于显示图片
                ImageView iv = (ImageView) view.findViewById(R.id.iv);
                iv.setImageResource(R.drawable.p4);
                //Toast中的内容之二TextView用于显示Toast的标题
                TextView title = (TextView) view.findViewById(R.id.tv_title);
                title.setText("注意:");
                //Toast中的内容之三TextView用于显示Toast的信息内容
                TextView text = (TextView) view.findViewById(R.id.tv_message);
                text.setText("这是完全自定义Toast");
                //创建一个Toast对象
                Toast toast = new Toast(MainActivity.this);
                //设置Toast的显示位置为屏幕的右上方
                toast.setGravity(Gravity.RIGHT | Gravity.TOP, 100,100);
                //设置Toast的显示时间
                toast.setDuration(Toast.LENGTH_LONG);
                //设置Toast显示的布局
                toast.setView(view);
                toast.show();

其实就是将一个布局文件显示在Toast上

在线程中使用:

Handler handler = new Handler();
       public void showToast() {
           handler.post(new Runnable() {
               @Override
               public void run() {
                   Toast.makeText(MainActivity.this, "线程中的Toast", Toast.LENGTH_LONG).show();
               }
           });
       }
new Thread(new Runnable() {
                   public void run() {
                       showToast();
                   }
               }).start();

如果直接在子线程Toast,那么就会报错,:Can’t create handler inside thread that has not called Looper.prepare().至于为什么会这样大家可以参考这个链接.上面有讲的很清楚.

相关标签: android toast优化