提示控件之自定义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”的分享。
- 提示控件之自定义Toast
- Android自定义控件之自定义Toast
- Android之自定义Toast提示框样式
- 自定义控件:自定义Toast
- 自定义Dialog, Toast提示
- 提示控件之自定义Dialog
- 自定义控件:Toast
- 自定义Toast,让提示更亲众
- React Native 自定义控件之验证码和Toast
- Android之自定义Toast
- 自定义Toast之WindowManager
- Toast之自定义
- Android 自定义View之消息提示控件
- Android消息提示之Toast
- Android开发之四(三):常用控件之提示(Toast)
- iOS开发系列之常用自定义控件开发集—Android的Toast控件开发
- toast提示控件使用(待写。。)
- ASP.NET自定义控件之Tips提示信息控件 (一)
- Leetcode 199(Java)
- pat甲级1010. Radix (25)
- @Repository @Service @Controller @Component
- Oracle11高性能开发--(2)索引
- Android 开源项目列表
- 提示控件之自定义Toast
- postgresql 数据库操作
- Spring事务的传播特性
- 0-1 Knapsack Problem
- 数据源
- 显示编译过程生成.a的通用Makefile
- Java:按值传递还是按引用传递详细解说
- [LintCode]Print Numbers by Recursion
- Windows 7上编译的Sophus