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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM