提示控件之自定义Toast

来源:互联网 发布:简支梁配筋计算软件 编辑:程序博客网 时间:2024/05/24 02:50

Toast使用简单,性能优良,在Android APP中使用非常广泛。

但实际开发中我们并不仅仅满足于系统提供Toast的简单使用,同一行代码在不同的Android手机上就可能有不同的显示样式。为了匹配统一的界面风格,我们需要对Toast的弹出位置,字体及样式做出一些自定义设置,以此来达到我们的目的。

闲话少说,直接开始我们的自定义旅程。

1.创建布局文件

新建layout_mytoast.xml,布局很简单,使用一个TextView文本,代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/my_toast_style"    android:gravity="center">    <TextView        android:id="@+id/id_text_message"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginBottom="10dp"        android:layout_marginLeft="15dp"        android:layout_marginRight="15dp"        android:layout_marginTop="10dp"        android:gravity="center"        android:textColor="#ffffff"        android:textSize="14sp" /></LinearLayout>

layout_mytoast.xml中使用了一个自定义的背景样式my_toast_style.xml,圆角和90%透明度的背景色,代码如下:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#90000000" />    <corners android:radius="5dp"/></shape>

2.自定义Toast

自定义MyToast类,继承Toast,按照屏幕的大小指定Toast的弹出位置,自定义makeText方法,根据id_text_message获取layout_mytoast.xml中TextView,并设置其文本,代码如下:

package com.alone.custome.toast;import android.app.Activity;import android.app.Application;import android.content.Context;import android.util.DisplayMetrics;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.WindowManager;import android.widget.TextView;import android.widget.Toast;import com.alone.R;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * Created by Alone on 2016/7/30. * 自定义Toast * 1.可自由设置样式与位置 * 2.实现了不受消息队列影响的Toast */public class MyToast extends Toast {    public static final int OFFEST_TOP = 1;//顶部弹出    public static final int OFFEST_CENTER = 2;//中部弹出    public static final int OFFEST_BOTTOM = 3;//底部弹出    private static Context mContext;    private Toast toast;    private View layout;    private boolean isShow;    /**     * 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 Application}     *                or {@link Activity} object.     */    private MyToast(Context context) {        super(context);        this.mContext = context;    }    public MyToast(Context context, CharSequence text, int yOffest) {        super(context);        LayoutInflater inflate = (LayoutInflater)                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);        layout = inflate.inflate(R.layout.layout_mytoast, null);        TextView tv = (TextView)layout.findViewById(R.id.id_text_message);        tv.setText(text);        toast = new Toast(context);        int offest = 0;        switch (yOffest) {            case OFFEST_TOP:                offest = -(int)(getScreenHeight() * 0.25);                break;            case OFFEST_CENTER:                break;            case OFFEST_BOTTOM:                offest = (int)(getScreenHeight() * 0.25);                break;        }        toast.setGravity(Gravity.CENTER_VERTICAL, 0, offest);    }    public static Toast makeText(Context context, CharSequence text, int duration) {        return makeText(context, text, duration, OFFEST_TOP);    }    public static Toast makeText(Context context, CharSequence text, int duration, int yOffest) {        MyToast result = new MyToast(context);        LayoutInflater inflate = (LayoutInflater)                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);        View v = inflate.inflate(R.layout.layout_mytoast, null);        TextView tv = (TextView)v.findViewById(R.id.id_text_message);        tv.setText(text);        result.setView(v);        //setGravity方法用于设置位置,此处为垂直居中,水平1/4,1/2,3/4        int offest = 0;        switch (yOffest) {            case OFFEST_TOP:                offest = -(int)(getScreenHeight() * 0.25);                break;            case OFFEST_CENTER:                break;            case OFFEST_BOTTOM:                offest = (int)(getScreenHeight() * 0.25);                break;        }        result.setGravity(Gravity.CENTER_VERTICAL, 0,  offest);        result.setDuration(duration);        return result;    }    /**     * 弹出永久存在的toast     */    public void showForever() {        //从Toast对象中获得mTN变量        try {            Field field = toast.getClass().getDeclaredField("mTN");            field.setAccessible(true);            Object obj = field.get(toast);            Field mNextView = obj.getClass().getDeclaredField("mNextView");            mNextView.setAccessible(true);            //TN对象中获得了show方法            Method mShow = obj.getClass().getDeclaredMethod("show");            //调用show方法来显示Toast信息提示框            mNextView.set(obj, layout);            mShow.invoke(obj, new Object[]{});            isShow = true;        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 关闭永久存在的toast     */    public void hideForever() {        //从Toast对象中获得mTN变量        try {            Field field = toast.getClass().getDeclaredField("mTN");            field.setAccessible(true);            Object obj = field.get(toast);            //TN对象中获得了hide方法            Method mShow = obj.getClass().getDeclaredMethod("hide");            //调用hide方法来显示Toast信息提示框            mShow.invoke(obj, new Object[]{});            isShow = false;        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 得到当前屏幕的高度     */    private static int getScreenHeight() {        WindowManager wm = (WindowManager) mContext                .getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        return outMetrics.heightPixels;    }    public void toggle() {        if (isShow) {            hideForever();        } else {            showForever();        }    }    public boolean isShow() {        return isShow;    }}

3.效果测试

创建一个测试Activity,点击按钮进行测试,分别弹出对话框。

Button ToastBomBtn = (Button) findViewById(R.id.id_btn_toast_bom);ToastBomBtn.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        MyToast.makeText(ToastActivity.this, "网络错误", Toast.LENGTH_SHORT, MyToast.OFFEST_BOTTOM).show();    }});Button ToastCtrBtn = (Button) findViewById(R.id.id_btn_toast_ctr);ToastCtrBtn.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        MyToast.makeText(ToastActivity.this, "网络错误", Toast.LENGTH_SHORT, MyToast.OFFEST_CENTER).show();    }});Button ToastTopBtn = (Button) findViewById(R.id.id_btn_toast_top);ToastTopBtn.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        MyToast.makeText(ToastActivity.this, "网络错误", Toast.LENGTH_SHORT).show();    }});

效果如下:
这里写图片描述

此处截取一张屏幕截图,不要关注文本的字体,和本实例没有关系,不过如果要实现Toast弹出特殊字体文本,项目中导入字体文件设置Typeface也是很容易实现的。如果要实现弹出一个✔️的图片提示表示操作成功,取一张背景透明的图在自定义布局文件中也是非常好实现的,既然是自定义布局,那么一切都可以根据实际需求来。

4.趣味扩展

前文的MyToast中还实现了一种不受消息队列影响的Toast,即创建一种永不消失的Toast,使用反射获取Toast中属性及show方法,弹出一个永不消失的Toast,并可以使用hide方法隐藏Toast,有兴趣的同学可以试一下,只要app不被杀死,Toast可以永远存在哦。好了,本期就到这里,下次进行“提示控件之自定义Dialog”的分享。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一岁半宝宝爱打人怎么办 两岁半宝宝喜欢打人怎么办 孩子总是挨欺负怎么办 一年级孩子爱打架怎么办 孩子没规矩家长怎么办 小朋友在幼儿园打人怎么办 幼儿园小朋友喜欢打人怎么办 三周岁宝宝爱哭怎么办 2周岁宝宝爱哭怎么办 一个月宝宝爱哭怎么办 2岁宝宝爱哭怎么办 三岁小朋友打人怎么办 一岁半小朋友喜欢打人怎么办 爷爷偏心我该怎么办 冲动型学生老师怎么办 两个宝宝争东西怎么办 2周岁宝宝打人怎么办 小孩幼儿园被打怎么办 小孩喝了润滑油怎么办 孩子被打了怎么办 宝宝吃了指甲油怎么办 孩子掉了深海怎么办 小孩打了别人怎么办 两岁宝宝爱咬人怎么办 孩子上学老打人怎么办 孩子上学爱说话怎么办 孩子抢玩具打人怎么办 生气就像打人怎么办 小孩总喜欢打人怎么办 小孩性格好翘怎么办 一岁小宝宝打人怎么办 小孩子老喜欢打人怎么办 孩子被大人欺负怎么办 小孩识字量少怎么办 父母打架孩子该怎么办 小孩嘴唇里面烂怎么办 幼儿园小朋友很调皮怎么办 幼儿园小朋友上课调皮怎么办 孩子误冲游戏怎么办 遇到别的熊孩子怎么办 幼儿园遇到熊孩子怎么办