Android自己定义Toast
一、引言
在开发的过程中你会发现Android自身的Toast提示有很多限制,比方我想自己定义Toast的动画、自己定义一个美观的View显示在Toast中、很多其它的是让Toast显示指定的时长等等。
首先一下效果怎样:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmd3ZWl3dG1kYmY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
二、原理
自己定义的原理也非常easy,就是给WindowManager加入View和删除View,只是须要设置WindowManager.LayoutParams和View的样式。使其看起来和Android系统的Toast看起来非常相像。
详细代码例如以下:
/**
* Custom Toast
*
* @author Lucky
*
*/
public class ToastHelper {
public static final int LENGTH_LONG = 3500;
public static final int LENGTH_SHORT = 2000;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowParams;
private View toastView;
private Context mContext;
private Handler mHandler;
private String mToastContent = "";
private int duration = 0;
private int animStyleId = android.R.style.Animation_Toast; private final Runnable timerRunnable = new Runnable() { @Override
public void run() {
removeView();
}
}; private ToastHelper(Context context) {
// Notice: we should get application context
// otherwise we will get error
// "Activity has leaked window that was originally added"
Context ctx = context.getApplicationContext();
if (ctx == null) {
ctx = context;
}
this.mContext = ctx;
mWindowManager = (WindowManager) mContext
.getSystemService(Context.WINDOW_SERVICE);
init();
} private void init() {
mWindowParams = new WindowManager.LayoutParams();
mWindowParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mWindowParams.alpha = 1.0f;
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
mWindowParams.format = PixelFormat.TRANSLUCENT;
mWindowParams.type = WindowManager.LayoutParams.TYPE_TOAST;
mWindowParams.setTitle("ToastHelper");
mWindowParams.packageName = mContext.getPackageName();
mWindowParams.windowAnimations = animStyleId;// TODO
mWindowParams.y = mContext.getResources().getDisplayMetrics().widthPixels / 5;
} @SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private View getDefaultToastView() { TextView view = new TextView(mContext);
view.setText(mToastContent);
view.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
view.setFocusable(false);
view.setClickable(false);
view.setFocusableInTouchMode(false);
view.setTextColor(android.graphics.Color.WHITE);
Drawable drawable = mContext.getResources().getDrawable(
android.R.drawable.toast_frame); if (Build.VERSION.SDK_INT < 16) {
view.setBackgroundDrawable(drawable);
} else {
view.setBackground(drawable);
}
return view;
} public void show() {
removeView();
if (toastView == null) {
toastView = getDefaultToastView();
}
mWindowParams.gravity = android.support.v4.view.GravityCompat
.getAbsoluteGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
android.support.v4.view.ViewCompat
.getLayoutDirection(toastView));
removeView();
mWindowManager.addView(toastView, mWindowParams);
if (mHandler == null) {
mHandler = new Handler();
}
mHandler.postDelayed(timerRunnable, duration);
} public void removeView() {
if (toastView != null && toastView.getParent() != null) {
mWindowManager.removeView(toastView);
mHandler.removeCallbacks(timerRunnable);
}
} /**
* @param context
* @param content
* @param duration
* @return
*/
public static ToastHelper makeText(Context context, String content,
int duration) {
ToastHelper helper = new ToastHelper(context);
helper.setDuration(duration);
helper.setContent(content);
return helper;
} /**
* @param context
* @param strId
* @param duration
* @return
*/
public static ToastHelper makeText(Context context, int strId, int duration) {
ToastHelper helper = new ToastHelper(context);
helper.setDuration(duration);
helper.setContent(context.getString(strId));
return helper;
} public ToastHelper setContent(String content) {
this.mToastContent = content;
return this;
} public ToastHelper setDuration(int duration) {
this.duration = duration;
return this;
} public ToastHelper setAnimation(int animStyleId) {
this.animStyleId = animStyleId;
mWindowParams.windowAnimations = this.animStyleId;
return this;
} /**
* custom view
*
* @param view
*/
public ToastHelper setView(View view) {
this.toastView = view;
return this;
}
}
另外分享一个自己定义的Anim:
1.显示Toast的动画:
<?xml version="1.0" encoding="utf-8"? >
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fillAfter="true" > <alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" /> <translate
android:fromYDelta="20%"
android:toYDelta="0%" /> <scale
android:fromXScale="0.5"
android:fromYScale="0.5"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" /> </set>
2.退出Toast的动画:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fillAfter="true" > <alpha
android:fromAlpha="1.0"
android:toAlpha="0.0" /> <translate
android:fromYDelta="0%"
android:toYDelta="20%" /> </set>
给WIndowManager中的View加入动画须要定义一个style,例如以下:
<style name="PopToast">
<item name="@android:windowEnterAnimation">@anim/anim_toast_enter</item>
<item name="@android:windowExitAnimation">@anim/anim_toast_exit</item>
</style>
最后能够依照例如以下的方式去使用:
ToastHelper
.makeText(this, "hello world 你好。哈拉雷速度发说得对",
ToastHelper.LENGTH_SHORT)
.setAnimation(R.style.PopToast).show();
三、參考资料:
SuperToast: https://github.com/JohnPersano/SuperToasts
Android自己定义Toast的更多相关文章
- Android 自己定义ScrollView ListView 体验各种纵向滑动的需求
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38950509.本文出自[张鸿洋的博客] 1.概述 群里的一个哥们有个需求是这种: ...
- Android自己定义组件系列【5】——进阶实践(2)
上一篇<Android自己定义组件系列[5]--进阶实践(1)>中对任老师的<可下拉的PinnedHeaderExpandableListView的实现>前一部分进行了实现,这 ...
- 46.Android 自己定义Dialog
46.Android 自己定义Dialog Android 自己定义Dialog 前言 提示Dialog 提示Dialog 效果图 菜单Dialog 菜单Dialog 效果图 DialogActivi ...
- Android 自己定义RecyclerView 实现真正的Gallery效果
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38173061 .本文出自:[张鸿洋的博客] 上一篇博客我使用自己定义Horizo ...
- android自己定义刷新类控件
android尽管定义了种类很丰富的控件.可是有的时候这些自己定义的控件还是不能满足我的要求,为了可以适配很多其它的需求,我们须要在原有的基础上进行自己定义控件. 今天我向大家介绍的就是android ...
- Android自己定义DataTimePicker(日期选择器)
Android自己定义DataTimePicker(日期选择器) 笔者有一段时间没有发表关于Android的文章了,关于Android自己定义组件笔者有好几篇想跟大家分享的,后期会记录在博客中.本篇 ...
- Android UI--自定义ListView(实现下拉刷新+加载更多)
Android UI--自定义ListView(实现下拉刷新+加载更多) 关于实现ListView下拉刷新和加载更多的实现,我想网上一搜就一堆.不过我就没发现比较实用的,要不就是实现起来太复杂,要不就 ...
- Android自己定义组件系列【7】——进阶实践(4)
上一篇<Android自己定义组件系列[6]--进阶实践(3)>中补充了关于Android中事件分发的过程知识.这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpa ...
- ANDROID自己定义视图——onLayout源代码 流程 思路具体解释
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 在自己定义view的时候.事实上非常easy.仅仅须要知道3步骤: 1.測量- ...
随机推荐
- vue2.0 引入font-awesome
网上的大部分教程复杂而且难看懂,其实两步就能搞定. 先cnpm install font-awesome --save引入依赖 然后在main.js引入 font-awesome/css/font-a ...
- Quartz在服务异常中断或者重启后,不执行之前漏掉的任务,重新运行下一次任务
Quartz默认重启后会执行之前的任务,所以如果不想执行之前漏掉的任务,需要设置一下两个地方: CRON triggers CronTrigger trigger = TriggerBuilder.n ...
- viewDidUnload,viewDidLoad,viewWillAppear,viewWillDisappear的作用以及区别
viewDidLoad:在视图加载后被调用 viewWillAppear:视图即将可见时调用.默认情况下不执行任何操作 viewDidAppear: 视图已完全过渡到屏幕上时调用 viewWillDi ...
- MySQL的DML和DQL 增删改查
DML和DQL 增删改查 SELECT * FROM grade --新增 insert -- 向年级表中新增3条数据INSERT INTO grade(gradeID,gradeName) VA ...
- Hadoop Hive概念学习系列之hive里的扩展接口(CLI、Beeline、JDBC)(十六)
<Spark最佳实战 陈欢>写的这本书,关于此知识点,非常好,在94页. hive里的扩展接口,主要包括CLI(控制命令行接口).Beeline和JDBC等方式访问Hive. CLI和B ...
- 【译】x86程序员手册19-6.3.2数据访问的约束
6.3.2 Restricting Access to Data 数据访问的约束 To address operands in memory, an 80386 program must load ...
- 05--QT常用的类
http://blog.csdn.net/HMSIWTV/article/category/1128561/2 Qt常用类(1)—— 开端 使用Qt进行编程必须对 Qt 中常用的类有一定的 ...
- smtplib.SMTPDataError: (554, b'DT:SPM 126 smtp
报错信息 smtplib.SMTPDataError: (554, b'DT:SPM 126 smtp7,DsmowAA3uguL7e1cyvkyFw--.22553S3 1559096715,ple ...
- Cesium学习笔记(四)Camera
http://blog.csdn.net/HobHunter/article/details/74909641 Cesium 相机控制场景中的视野.操作相机的方法有很多,如旋转,缩放,平移和飞到目的地 ...
- Centos7安装gitlab服务器
1.先按照官方教程 https://about.gitlab.com/downloads/#centos7 大概内容如下: 1. Install and configure the necessary ...