Android自定義組件系列【17】——教你如何高仿微信錄音Toast

一、Toast介紹

平時我們在Android開發中會經常用到一個叫Toast的東西,官方解釋如下

A toast is a view containing a quick little message for the user. The toast class helps you create and show those.
When the view is shown to the user, appears as a floating view over the application. It will never receive focus. The user will probably be in the middle of typing something else. The idea is to be as unobtrusive as possible, while still showing the user the information you want them to see. Two examples are the volume control, and the brief message saying that your settings have been saved.

Toast最基本的用法很簡單,不用說大家都會(這裏切記要調用show()去顯示)

public static void showToast(Context context){
    Toast.makeText(context, "歡迎關注水寒的CSDN博客", Toast.LENGTH_LONG).show();
}

這裏寫圖片描述

二、自定義Toast

上面的Toast一般顯示在手機偏下的一個位置上,有的時候我們需要將這個Toast的位置或者內容進行修改,比如讓顯示在屏幕中間,讓內容裏面有圖片,這樣的修改也比較容易,Toast有一個和ActionBar類似的方法setView(),這個方法就是提供給我們自定義Toast的。

這裏寫圖片描述

public static void showToast(Context context){
    LayoutInflater inflater = LayoutInflater.from(context);
    View toastView = inflater.inflate(R.layout.toast_test_custome, null);
    Toast toast = new Toast(context); 
    toast.setDuration(3000);
    toast.setView(toastView);                //設置自定義view
    toast.setGravity(Gravity.CENTER, 0, 0);  //控制顯示到屏幕中間
    toast.show();                            //注意:一定要調用才能顯示
}

佈局文件如下

<?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/custom_toast_bg"
    android:padding="15dip"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <ImageView 
        android:layout_width="80dip"
        android:layout_height="80dip"
        android:scaleType="centerCrop"
        android:src="@drawable/shuihan"/>

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dip"
        android:textSize="16sp"
        android:text="歡迎訪問水寒的CSDN博客"
        android:textColor="#ffffff"/>
</LinearLayout>

三、爲什麼要改變Toast的顯示時長

上面的自定義非常簡單,但是我們要改變Toast的顯示時間就比較麻煩了,因爲toast的setDuration方法只能填寫兩個值2000ms或者3000ms
這裏寫圖片描述
不信你可以給setDuration設置一個10000它最長只顯示3s,網上有各種延長Toast的方法,基本上都是通過定時器來延長顯示的。
那麼我們接下來就要思考一個問題了,我們爲什麼要延遲Toast的時間?爲什麼不用Dialog或者PopupWindow來替代?
其實原因很簡單,Toast顯示是不獲取焦點的,所以Toast一般是用來提示用戶的,而不影響用戶的操作。我們可以用一個很簡單的例子證明一下:

findViewById(R.id.test_toast_button).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //showToast();
            showDialog();
            Log.d("shuihan", "----down----");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d("shuihan", "----move----");
            break;
        case MotionEvent.ACTION_UP:
            Log.d("shuihan", "----up----");
            break;
        case MotionEvent.ACTION_CANCEL:
            Log.d("shuihan", "----cancel----");
            break;
        default:
            break;
        }
        return true;
    }
});

我們分別去在ACTION_DOWN的時候去顯示一下toast和dialog你再對照輸出日誌看一下,就會明白。
我們在微信裏面錄音的時候會有一個Toast大家應該都見過,如下:
這裏寫圖片描述
這個Toast的一個很重要的特點就是隻要你按着不放它就不消失,也就是說它的顯示時間可以長於3s

四、實現顯示時間長於3s的Toast

(本文出自水寒的CSDN博客:http://blog.csdn.net/dawanganban
我們採用的方式也是使用定時器來實現重複顯示一個toast從而延長它的時間,我們先來看一個androd裏面的CountDownTimer的用法

 new CountDownTimer(30000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

這是官方文檔上的一個例子,一個30s的倒計時,每隔1s調用一次onTick方法,該方法返回一個倒計時剩餘時間,ok,接下來我們來看看toast怎麼讓他顯示30s

    /**
     * 顯示Toast
     * @param toast
     * @param duration
     */
    public static void showToast(final Toast toast, long duration, final OnToastStatus toastStatu) {
        final long tickTime = 200;
        mCountDownTimer = new CountDownTimer(duration, tickTime) {
            @Override
            public void onTick(long millisUntilFinished) {
                if(millisUntilFinished <= 200){
                    showToast("最長可錄製一分鐘");
                }else{
                    toast.show();
                }
            }

            @Override
            public void onFinish() {
                toast.cancel();
                if(toastStatu != null){
                    toastStatu.toastStop();
                }
            }
        }.start();
    }

    public interface OnToastStatus{
        public void toastStop();
    }

    /**
     * 停止顯示Toast
     */
    public static void stopToast(Toast toast){
        if(toast != null){
            toast.cancel();
        }
        if(mCountDownTimer != null){
            mCountDownTimer.cancel();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章