[Android] 定製化Toast展示(位置、底色、圓角)

csdn_lexli發表於2016-09-10

【需求分析】

  我們知道windows上除錯程式輸出變數可以通過MessageBox彈窗到螢幕上展示。在Android系統裡通過Toast可以實現類似的彈窗效果。系統的Toast預設彈出到螢幕底部,且樣式一般比較老舊。
  這次的需求就是自定義Toast,可以規定Toast展示的位置以及Toast樣式,具體來說包括三個方面:1. Toast位置自定義 2. Toast外部樣式自定義 3. Toast顏色自定義

【動畫效果】

  對比系統自帶和定製化Toast的展示效果
  系統Toast及自定義Toast對比

【實現方案】

  自定義Toast的設計核心就是在系統Toast外邊套一層View,將系統toast作為整個自定義Toast的一部分進行展示。具體來看通過系統Toast的setGravity設定Toast的顯示位置。通過外面包裹的一層View對應的xml設定外層Toast的樣式。

【程式碼展示】

  首先是整個測試程式碼部分:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn1 = (Button) findViewById(R.id.btn_sys_toast);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "這個是系統自帶的Toast", Toast.LENGTH_SHORT).show();
            }
        });

        Button btn2 = (Button) findViewById(R.id.btn_custom_toast);
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int xOffset = 0, yOffset = -300;
                CustomToast.makeText(MainActivity.this, "這是自定義彈出的Toast",
                        Toast.LENGTH_SHORT, xOffset, yOffset).show();
            }
        });
    }
}

  這裡通過LayoutInflater構造了系統toast外層的父控制元件toastRoot。樣式的改變可以直接修復toastRoot對應的xml。Toast位置的改變直接呼叫系統原生Toast的setGravity實現

import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 自定義Toast
 *      1. 能夠改變Toast出現的位置 (系統預設在螢幕下方彈出)
 *      2. 改變Toast的邊角,改為具有弧度的邊角 round_corner_toast.xml配置 radius=“4”
 *      3. Toast底色可變  round_corner_toast.xml配置,目前底色 35383D
 */
public class CustomToast {
    public static final int LENGTH_SHORT = 0;
    public static final int LENGTH_LONG = 1;

    Toast toast;
    TextView tvToastText;
    Context context;

    public CustomToast(Context context) {
        this.context = context;
        toast = new Toast(context);

        /**
         * 這裡:根據自定義的toast xml樣式進行載入展示,類似於其他xml對應的view一樣
         *      通過InflaterLayout 展示整個rootView 再將內部的toast附著在這個viewRoot上
         */
        LayoutInflater inflater = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View toastRoot = inflater.inflate(R.layout.custom_toast, null);
        tvToastText = (TextView) toastRoot.findViewById(R.id.toast_text);

        toast.setView(toastRoot);
    }

    public void setDuration(int duration) {
        toast.setDuration(duration);
    }

    public void setText(CharSequence text) {
        tvToastText.setText(text);
    }


    /**
     * 這裡預設選用螢幕中心為座標原點,
     * @param xOffset X軸偏離中心的距離(往右為正)
     * @param yOffset Y軸偏離中心的距離(往下為正)
     */
    public void setGravity(int xOffset, int yOffset) {
        toast.setGravity(Gravity.CENTER, xOffset, yOffset);
    }

    /**
     *
     * @param context
     * @param text     toast展示文字
     * @param duration toast展示時間
     * @param xOffset  設定toast偏離中心X方向的距離
     * @param yOffset  設定toast偏離中心Y方向的距離
     * @return
     */
    public static CustomToast makeText(Context context, CharSequence text, int duration, int xOffset, int yOffset ) {
        CustomToast customedToast = new CustomToast(context);
        customedToast.setText(text);
        customedToast.setDuration(duration);
        customedToast.setGravity(xOffset, yOffset);
        return customedToast;
    }

    public void show() {
        toast.show();
    }
}

  自定義Toast用到的資源,首先是custom_toast.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/toast_text"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textColor="#FFFFFF"
        android:textSize="14sp"
        android:gravity="center"
        android:background="@drawable/round_corner_toast" />
</LinearLayout>

  為了設定圓角效果,美化自定義Toast展示效果將TextView的背景設定為圓角的樣式,具體在round_corner_toast.xml中:Toast背景色可以通過android:color進行配置以及toast的透明度。圓角弧度通過android:radius設定

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#B335383D" />
    <corners android:radius="4dp" />
</shape>

【個人總結】

  1. 自定義Toast可以通過LayoutInflater包裹一個系統Toast實現
  2. 自定義Toast樣式可以直接在xml中配置

相關文章