Toast是安卓非常常用的消息弹框之一,但是原生的弹框过于朴素,无法适应不同场景的样式需求,因此设计一个类似于Toasty的弹框构建工具。
不废话直接上代码
import android.content.Context;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout.LayoutParams;
import androidx.annotation.Nullable;
import com.cpk.yeahtoast.R.color;
import com.cpk.yeahtoast.R.drawable;
/**
*Yet Another Toast Util.
*@author pinkman
*/
public class YeahToast {
private static final String TAG = YeahToast.class.getSimpleName();
public static final int STYLE_NO = 0;
public static final int STYLE_INFO = 1;
public static final int STYLE_WARN = 2;
public static final int STYLE_ERROR = 3;
public static final int STYLE_SUCCESS = 4;
private static YeahToast.StyleToast styleToast = null;
public static void show(Context context, String text, @Nullable Integer length) {
show(context, STYLE_NO , text, length);
}
public static void showInfo(Context context, String text, @Nullable Integer length) {
prepare(context, STYLE_INFO , text, length).show();
}
public static void showError(Context context, String text, @Nullable Integer length) {
prepare(context, STYLE_ERROR , text, length).show();
}
public static void showWarn(Context context, String text, @Nullable Integer length) {
prepare(context, STYLE_WARN , text, length).show();
}
public static void showSuccess(Context context, String text, @Nullable Integer length) {
prepare(context, STYLE_SUCCESS , text, length).show();
}
protected static StyleToast prepare(Context context, int style, String text, @Nullable Integer length) {
if (styleToast != null) {
styleToast.cancel();
}
styleToast = new YeahToast.StyleToast(context, style, text, length);
return styleToast;
}
}
StyleToast是用于设置Toast样式的封装类,可以设为子类,也可以新建一个类。带样式的弹框是用Toast的setView方法将一个自定义的布局作为toast显示内容,本封装类设置Toast的布局有一个图标和文本。
/**
*@author pinkman
*/
public static class StyleToast {
Toast toast;
ViewGroup view;
TextView tv;
ImageView icon;
public StyleToast(Context context, int style, String message, @Nullable Integer length) {
this.toast = new Toast(context);
this.view = new LinearLayout(context);
this.view.setPadding(8, 8, 8, 8);
this.tv = new TextView(context);
LayoutParams imageLp = new LayoutParams(-2, -2);
imageLp.setMargins(8, 8, 8, 8);
this.icon = new ImageView(context);
this.icon.setScaleType(ScaleType.FIT_CENTER);
this.icon.setLayoutParams(imageLp);
LayoutParams textLp = new LayoutParams(-2, -2);
textLp.setMargins(8, 8, 8, 8);
this.tv.setTextSize(16.0F);
this.tv.setTextColor(context.getResources().getColor(color.colorWhite));
this.tv.setText(message);
this.tv.setGravity(17);
this.tv.setTextAlignment(4);
this.tv.setLayoutParams(textLp);
this.view.addView(this.icon);
this.view.addView(this.tv);
this.view.setLayoutParams(new android.view.ViewGroup.LayoutParams(-2, -2));
this.toast.setView(this.view);
this.toast.setDuration(length == null ? 0 : length);
switch(style) {
case 1:
this.view.setBackgroundResource(drawable.toast_style_info);
this.icon.setImageResource(drawable.ic_error_outline_white_24dp);
break;
case 2:
this.view.setBackgroundResource(drawable.toast_style_warn);
this.icon.setImageResource(drawable.ic_warning_white_24dp);
break;
case 3:
this.view.setBackgroundResource(drawable.toast_style_error);
this.icon.setImageResource(drawable.ic_close_white_24dp);
break;
case 4:
this.view.setBackgroundResource(drawable.toast_style_success);
this.icon.setImageResource(drawable.ic_done_black_24dp);
break;
default:
this.view.setBackgroundResource(drawable.toast_style_default);
this.icon.setVisibility(8);
}
}
public void show() {
this.toast.show();
}
private void cancel() {
this.toast.cancel();
}
}
所有资源都是xml文件,放在drawable里。
<!--边框-->
<!--toast_style_warn.xml-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<stroke android:width="0.8dp"
android:color="#555"/>
<solid android:color="#FA5324"/>
<corners android:bottomRightRadius="16dp"
android:bottomLeftRadius="16dp"
android:topRightRadius="16dp"
android:topLeftRadius="16dp"
/>
</shape>
<!--toast_style_success.xml-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<stroke android:width="0.8dp"
android:color="#666"/>
<solid android:color="#4FEE5F"/>
<corners android:bottomRightRadius="16dp"
android:bottomLeftRadius="16dp"
android:topRightRadius="16dp"
android:topLeftRadius="16dp"
/>
</shape>
<!--toast_style_error.xml-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<stroke android:width="0.8dp"
android:color="#888"/>
<solid android:color="#EE2344"/>
<corners android:bottomRightRadius="16dp"
android:bottomLeftRadius="16dp"
android:topRightRadius="16dp"
android:topLeftRadius="16dp"
/>
</shape>
<!--toast_style_info.xml-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<stroke android:width="0.8dp"
android:color="#555"/>
<solid android:color="#3366A5"/>
<corners android:bottomRightRadius="16dp"
android:bottomLeftRadius="16dp"
android:topRightRadius="16dp"
android:topLeftRadius="16dp"
/>
</shape>
<!--toast_style_default.xml-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<stroke android:width="0.8dp"
android:color="#EEE"/>
<solid android:color="#888"/>
<corners android:bottomRightRadius="16dp"
android:bottomLeftRadius="16dp"
android:topRightRadius="16dp"
android:topLeftRadius="16dp"
/>
</shape>
<!--------------------------------------------------------------------------------->
<!--ic_error_outline_white_24dp.xml-->
<vector android:height="24dp" android:tint="#FDFDFD"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
<!--ic_close_white_24dp.xml-->
<vector android:height="24dp" android:tint="#FDFDFD"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
<!--ic_warning_white_24dp.xml-->
<vector android:height="24dp" android:tint="#FDFDFD"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
</vector>
<!--ic_done_white_24dp.xml-->
<vector android:height="24dp" android:tint="#FDFDFD"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
</vector>
使用方式很简单,比如想在Activity弹出一个长警告就用YeahToast.showWarn(this,"warn!",Toast.LENGTH_LONG);
因为Toast是系统默认的一种弹窗,无法自定义时长,只能为Toast.LENGTH_SHORT(2.5秒)或Toast.LENGTH_LONG(3秒),对自定义的支持不是很好,而且显示内容也受限制(比如不能播放声音),在Android9版本中甚至不支持播放长Toast,且在11版本中弃用了setView方法,这意味着本工具类可能就要失效了。