• ToastMiui【仿MIUI的带有动画的Toast】


    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    仿MIUI的带有动画的Toast

    效果图

     

    代码分析

    • ToastMiui类基于WindowManager

    • 为了和Toast用法保持一致,ToastMiui类中也使用了makeText、show、setGravity、setText方法。方便在项目中直接替换Toast。

    使用步骤

    一、项目组织结构图

     

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    将ToastMiui复制到项目中,并重新import R文件

    package com.why.project.toastmiuidemo.views;
    
    import android.content.Context;
    import android.graphics.PixelFormat;
    import android.os.Handler;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.TextView;
    
    import com.why.project.toastmiuidemo.R;
    
    /**
     * CreateBy HaiyuKing
     * Used 仿MIUI的带有动画的Toast效果实现,基于WindowManager【可以控制显示样式、位置、显示时间、动画,不可触发】
     * 注意 Toast布局在源码中的布局是采用LinearLayout
     */
    public class ToastMiui {
    
        /**显示的时间(长)*/
        public static final int LENGTH_LONG = 3500;
        /**显示的时间(短)*/
        public static final int LENGTH_SHORT = 2000;  
        
        private WindowManager mWindowManager;//整个Android的窗口机制是基于一个叫做 WindowManager
        private View mToastView;
        private WindowManager.LayoutParams mParams;
        
        private Handler mHandler;
        private Context mContext;
        
        private int mShowTime = LENGTH_SHORT;//记录Toast的显示长短类型LENGTH_LONG/LENGTH_SHORT
        private boolean mIsShow;//记录当前Toast的内容是否已经在显示
    
        /**
         * 逻辑简单粗暴,直接调用构造函数实例化一个MiuiToast对象并返回。*/
        public static ToastMiui MakeText(Context context, CharSequence text, int duration) {
            ToastMiui toastMiui = new ToastMiui(context, text, duration);
            return toastMiui;
        }
        
        public static ToastMiui MakeText(Context context, int toastStrId, int showTime) {
            ToastMiui toastMiui = new ToastMiui(context, context.getString(toastStrId), showTime);
            return toastMiui;
        }
    
        /**在构造方法中,更多的是对数据的初始化,由于设置布局参数比较多,所以单独抽出一个函数来*/
        private ToastMiui(Context context, CharSequence text, int duration){
            mContext = context;
            mShowTime = duration;//记录Toast的显示长短类型
            mIsShow = false;//记录当前Toast的内容是否已经在显示
    
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            //通过inflate获取自定义的Toast布局文件
            mToastView = LayoutInflater.from(context).inflate(R.layout.toast_custom_view,null);
            TextView tv = (TextView) mToastView.findViewById(R.id.tv_toast);
            tv.setText(text);
            //设置布局参数
            setParams();
        }
    
        /**设置布局参数
         * 这个设置参数更多是参考源代码中原生Toast的设置参数的类型
         * 在这里我们需要注意的是 mParams.windowAnimations = R.style.anim_view;这个是我们这个仿MIUI的Toast动画实现的基石。*/
        private void setParams() {
            mParams = new WindowManager.LayoutParams();
            mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  
            mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
            mParams.format = PixelFormat.TRANSLUCENT;  
            mParams.windowAnimations = R.style.anim_view;//设置进入退出动画效果
            mParams.type = WindowManager.LayoutParams.TYPE_TOAST;  
            mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON  
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
            mParams.alpha = 1.0f;  
            mParams.setTitle("ToastMiui");
            mParams.packageName = mContext.getPackageName();
            
            mParams.gravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;//设置显示的位置
            mParams.y = 50;//设置偏移量
        }
    
        /**
         * 1、gravity是输入Toast需要显示的位置,例如CENTER_VERTICAL(垂直居中)、CENTER_HORIZONTAL(水平居中)、TOP(顶部)等等。
         * 2、xOffset则是决定Toast在水平方向(x轴)的偏移量,偏移量单位为,大于0向右偏移,小于0向左偏移
         * 3、yOffset决定Toast在垂直方向(y轴)的偏移量,大于0向下偏移,小于0向上偏移,想设大值也没关系,反正Toast不会跑出屏幕。*/
        public void setGravity(int gravity, int xOffset, int yOffset) {
            mParams.gravity = gravity;
            mParams.x = xOffset;
            mParams.y = yOffset;
        }
    
        public void setText(CharSequence s){
            TextView tv = (TextView) mToastView.findViewById(R.id.tv_toast);
            tv.setText(s);
        }
    
        public void setText(int resId){
            TextView tv = (TextView) mToastView.findViewById(R.id.tv_toast);
            tv.setText(resId);
        }
        
        public void show() {
            if(!mIsShow) {//如果Toast没有显示,则开始加载显示
                mIsShow = true;
                mWindowManager.addView(mToastView, mParams);
                if (mHandler == null) {
                    mHandler = new Handler();
                }
                mHandler.postDelayed(timerRunnable, mShowTime);
            }
        } 
        
        private final Runnable timerRunnable = new Runnable() {
            @Override  
            public void run() {
                removeView();
            }  
        };  
        
        public void removeView() {  
            if (mToastView != null && mToastView.getParent() != null) {  
                mWindowManager.removeView(mToastView);
                mHandler.removeCallbacks(timerRunnable);
                mIsShow = false;
            }
        }  
    }
    ToastMiui.java

    将toast_custom_view.xml文件复制到项目中

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 自定义显示风格的Toast的布局文件 -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toast_custom_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/toast_custom_view_bg"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/tv_toast"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="@dimen/toast_custom_text_paddingTB"
            android:paddingBottom="@dimen/toast_custom_text_paddingTB"
            android:paddingLeft="@dimen/toast_custom_text_paddingLR"
            android:paddingRight="@dimen/toast_custom_text_paddingLR"
            android:text=""
            android:textColor="@android:color/white"
            android:textSize="@dimen/toast_custom_text_size"/>
    
    </LinearLayout>
    toast_custom_view.xml

    将toast_custom_view_bg.xml文件复制到项目中

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 自定义显示风格的Toast的布局文件的背景 -->
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
        <!-- 圆角 -->
        <corners android:radius="@dimen/toast_custom_view_bg_corners" />
        <!-- 描边 -->
        <stroke
            android:width="1dp"
            android:color="#666666" />
        <!-- 填充 -->
        <solid android:color="#666666" />
    
    </shape>
    toast_custom_view_bg.xml

    将toast_anim_in.xml文件复制到项目中

    <?xml version="1.0" encoding="utf-8"?>
    <!-- ToastMiui【仿小米带有动画的Toast】进入动画 -->
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="0"
            android:toYDelta="85"
            android:duration="1"
            />
        <translate
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="0"
            android:toYDelta="-105"
            android:duration="350"
            android:fillAfter="true"
            android:interpolator="@android:anim/decelerate_interpolator"
            />
        <alpha 
            android:fromAlpha="0"
            android:toAlpha="1"
            android:duration="100"
            />
        <translate
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="0"
            android:toYDelta="20"
            android:duration="80"
            android:fillAfter="true"
            android:startOffset="350"
            />
    </set>
    toast_anim_in.xml

    将toast_anim_out.xml文件复制到项目中

    <?xml version="1.0" encoding="utf-8"?>
    <!-- ToastMiui【仿小米带有动画的Toast】退出动画 -->
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <alpha 
            android:fromAlpha="1"
            android:toAlpha="0"
            android:duration="800"/>
    </set>
    toast_anim_out.xml

    在dimens.xml中添加以下颜色标记的代码

    <resources>
        <!-- Default screen margins, per the Android Design guidelines. -->
        <dimen name="activity_horizontal_margin">16dp</dimen>
        <dimen name="activity_vertical_margin">16dp</dimen>
    
        <!-- **************自定义显示风格的Toast布局文件********************* -->
        <!-- 提示文字的大小 -->
        <dimen name="toast_custom_text_size">18sp</dimen>
        <!-- 提示文字的内边距(上下) -->
        <dimen name="toast_custom_text_paddingTB">10dp</dimen>
        <!-- 提示文字的内边距(左右) -->
        <dimen name="toast_custom_text_paddingLR">20dp</dimen>
        <!-- 背景的圆角 -->
        <dimen name="toast_custom_view_bg_corners">30dp</dimen>
    </resources>

    在styles.xml文件中添加以下颜色标记的代码

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
        <!-- ToastMiui【仿小米带有动画的Toast】进入动画和退出动画的引用 -->
        <style name="anim_view">
            <item name="@android:windowEnterAnimation">@anim/toast_anim_in</item>
            <item name="@android:windowExitAnimation">@anim/toast_anim_out</item>
        </style>
    
    </resources>

    三、使用方法

      ToastMiui toastMiui = ToastMiui.MakeText(this,"仿MIUI的带有动画的Toast",ToastMiui.LENGTH_LONG);
      toastMiui.show();

    如果想要修改文本或者显示位置,参考下面的代码:

    ToastMiui toastMiui = ToastMiui.MakeText(this,"仿MIUI的带有动画的Toast",ToastMiui.LENGTH_LONG);
    toastMiui.setText(getResources().getString(R.string.app_name));
    toastMiui.setGravity(Gravity.CENTER,0,0);
    toastMiui.show();

    混淆配置

    参考资料

    Android应用系列:仿MIUI的Toast动画效果实现(有图有源码)

    http://www.cnblogs.com/net168/p/4237528.html?utm_source=tuicool&utm_medium=referral

    Android:剖析源码,随心所欲控制Toast显示

    http://www.cnblogs.com/net168/p/4058193.html

    Android自定义Toast

    http://blog.csdn.net/zhangweiwtmdbf/article/details/30031015

    项目demo下载地址

    https://github.com/haiyuKing/ToastMiuiDemo

  • 相关阅读:
    Python之路,day16-Python基础
    Python之路,day15-Python基础
    Python之路,day14-Python基础
    django之model操作
    django信号
    django缓存
    CSRF的攻击与防范
    cookie和session
    http协议之Request Headers
    ajax参数详解
  • 原文地址:https://www.cnblogs.com/whycxb/p/6834542.html
Copyright © 2020-2023  润新知