简易自定义Toast
public class MainActivity extends ListActivity { private WindowManager wm; private WindowManager.LayoutParams params; private TextView textview; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { //如果没有add或add后已经remove,则再次remove时会报异常 wm.removeView(textview); } }; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] array = { "开启自定义的Toast", "3秒后关闭Toast", "", }; setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>(Arrays.asList(array)))); //加载布局文件(toast的布局、外观) textview = new TextView(this); textview.setText("真正的自定义Toast"); textview.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); textview.setPadding(20, 10, 20, 10); textview.setGravity(Gravity.CENTER); textview.setBackgroundColor(0xff0000ff); //设置窗体的参数 params = new WindowManager.LayoutParams(); params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;//最主要的是Flag_keep_screen_on,保持在屏幕上方 params.format = PixelFormat.TRANSLUCENT;//透明 params.type = WindowManager.LayoutParams.TYPE_TOAST;//样式类型为:TOast //窗体管理者 wm = (WindowManager) getSystemService(WINDOW_SERVICE); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { switch (position) { case 0: wm.addView(textview, params);//添加到窗体管理器上 break; case 1: mHandler.sendEmptyMessageDelayed(1, 3 * 1000); break; } }}
Activity
public class MainActivity extends ListActivity { private CToast mCToast; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] array = { "普通Toast", "测试默认吐司的位置", "自定义吐司位置", // "防止Toast重复显示", "带图片的吐司", "完全自定义的吐司", // "显示自定义时长的吐司", "隐藏自定义时长的吐司", }; setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>(Arrays.asList(array)))); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { switch (position) { case 0: Toast.makeText(this, "普通Toast", Toast.LENGTH_SHORT).show(); break; case 1: Toast toast = Toast.makeText(this, "测试默认吐司的位置", Toast.LENGTH_SHORT); int yOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()); toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, yOffset);//默认值是距离底部一段距离 toast.show(); break; case 2: toast = Toast.makeText(this, "自定义吐司位置", Toast.LENGTH_SHORT); toast.setGravity(Gravity.RIGHT | Gravity.BOTTOM, 50, 100); toast.show(); break; case 3: ToastUtils.toast(this, "防止Toast重复显示"); break; case 4: ToastUtils.toastWithPic(this, "带图片显示的吐司", R.drawable.ic_launcher); break; case 5: ToastUtils.showCustomToast(this, Toast.LENGTH_SHORT, "标题", "完全自定义的吐司", R.drawable.ic_launcher); break; case 6: if (null != mCToast) mCToast.hide(); mCToast = CToast.makeText(getApplicationContext(), "显示自定义时长的吐司", 5000); mCToast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,// (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics())); mCToast.show(); break; case 7: if (null != mCToast) mCToast.hide(); break; } }}
工具类
public class ToastUtils { /**防止Toast重复显示。原理就是,之前每执行一次Toast.makeText就创建一个新的对象,而现在只有一个对象 */ private static Toast mToast; /**防止Toast重复显示*/ public static void toast(Context context, String text) { toast(context, text, Toast.LENGTH_SHORT, -1); } /**带图片的吐司*/ public static void toastWithPic(Context context, String text, int resId) { toast(context, text, Toast.LENGTH_SHORT, resId); } /**如果连续多次调用此方法,吐司显示时长不会累积,而是以最后一次调用时的时间为起始时间*/ public static void toast(Context context, String text, int duration, int resId) { if (mToast == null) { mToast = Toast.makeText(context.getApplicationContext(), text, duration);//这里要用ApplicationContext,否则可能会内存泄漏 } else { mToast.setText(text); mToast.setDuration(duration); } LinearLayout toastView = (LinearLayout) mToast.getView();//吐司的布局是一个LinearLayout int viewCount = toastView.getChildCount(); if (resId == -1) { if (viewCount > 1) {//如果有超过1个的子view,说明里面有一个图片 toastView.removeViewAt(0);//移除掉图片 } } else { if (viewCount <= 1) {//如果有少于2个的子view,说明里面没有图片 ImageView imageCodeProject = new ImageView(context.getApplicationContext()); imageCodeProject.setImageResource(resId); toastView.addView(imageCodeProject, 0);//index the position at which to add the child } } mToast.show(); } private static Toast mCustomToast; /**完全自定义的吐司*/ public static void showCustomToast(Context context, int duration, String title, String content, int resId) { if (mCustomToast == null) { View layout = LayoutInflater.from(context).inflate(R.layout.toast, null); ((ImageView) layout.findViewById(R.id.tvImageToast)).setImageResource(resId); ((TextView) layout.findViewById(R.id.tvTitleToast)).setText(title); ((TextView) layout.findViewById(R.id.tvTextToast)).setText(content); mCustomToast = new Toast(context.getApplicationContext()); mCustomToast.setView(layout); mCustomToast.setDuration(duration); } mCustomToast.show(); }}
自定义时长的吐司
public class CToast { public static CToast makeText(Context context, CharSequence text, int duration) { CToast result = new CToast(context); LinearLayout mLayout = new LinearLayout(context); TextView tv = new TextView(context); tv.setText(text); tv.setTextColor(Color.BLACK); tv.setPadding(30, 20, 30, 20); tv.setGravity(Gravity.CENTER); GradientDrawable gradientDrawable = new GradientDrawable(); gradientDrawable.setCornerRadius(10);//边角 gradientDrawable.setGradientType(GradientDrawable.RECTANGLE);//矩形 gradientDrawable.setColor(Color.YELLOW);//填充色 gradientDrawable.setStroke(3, Color.WHITE);//描边 mLayout.setBackground(gradientDrawable); mLayout.addView(tv); result.mNextView = mLayout; result.mDuration = duration; return result; } public static final int LENGTH_SHORT = 2000; public static final int LENGTH_LONG = 3500; private final Handler mHandler = new Handler(); private int mDuration = LENGTH_SHORT; private int mGravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; private int mX, mY; private float mHorizontalMargin; private float mVerticalMargin; private View mView; private View mNextView; private WindowManager mWM; private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); public CToast(Context context) { init(context); } /** * Set the view to show. * @see #getView */ public void setView(View view) { mNextView = view; } /** * Return the view. * @see #setView */ public View getView() { return mNextView; } /** * Set how long to show the view for. * @see #LENGTH_SHORT * @see #LENGTH_LONG */ public void setDuration(int duration) { mDuration = duration; } /** * Return the duration. * @see #setDuration */ public int getDuration() { return mDuration; } /** * Set the margins of the view. * * @param horizontalMargin The horizontal margin, in percentage of the * container width, between the container's edges and the * notification * @param verticalMargin The vertical margin, in percentage of the * container height, between the container's edges and the * notification */ public void setMargin(float horizontalMargin, float verticalMargin) { mHorizontalMargin = horizontalMargin; mVerticalMargin = verticalMargin; } /** * Return the horizontal margin. */ public float getHorizontalMargin() { return mHorizontalMargin; } /** * Return the vertical margin. */ public float getVerticalMargin() { return mVerticalMargin; } /** * Set the location at which the notification should appear on the screen. * @see android.view.Gravity * @see #getGravity */ public void setGravity(int gravity, int xOffset, int yOffset) { mGravity = gravity; mX = xOffset; mY = yOffset; } /** * Get the location at which the notification should appear on the screen. * @see android.view.Gravity * @see #getGravity */ public int getGravity() { return mGravity; } /** * Return the X offset in pixels to apply to the gravity's location. */ public int getXOffset() { return mX; } /** * Return the Y offset in pixels to apply to the gravity's location. */ public int getYOffset() { return mY; } /** * schedule handleShow into the right thread */ public void show() { mHandler.post(mShow); if (mDuration > 0) { mHandler.postDelayed(mHide, mDuration); } } /** * schedule handleHide into the right thread */ public void hide() { mHandler.post(mHide); } private final Runnable mShow = new Runnable() { public void run() { handleShow(); } }; private final Runnable mHide = new Runnable() { public void run() { handleHide(); } }; private void init(Context context) { final WindowManager.LayoutParams params = mParams; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.windowAnimations = android.R.style.Animation_Toast; params.type = WindowManager.LayoutParams.TYPE_TOAST; params.setTitle("Toast"); mWM = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE); } private void handleShow() { if (mView != mNextView) { // remove the old view if necessary handleHide(); mView = mNextView; // mWM = WindowManagerImpl.getDefault(); final int gravity = mGravity; mParams.gravity = gravity; if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { mParams.horizontalWeight = 1.0f; } if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { mParams.verticalWeight = 1.0f; } mParams.x = mX; mParams.y = mY; mParams.verticalMargin = mVerticalMargin; mParams.horizontalMargin = mHorizontalMargin; if (mView.getParent() != null) { mWM.removeView(mView); } mWM.addView(mView, mParams); } } private void handleHide() { if (mView != null) { if (mView.getParent() != null) { mWM.removeView(mView); } mView = null; } }}
自定义吐司布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llToast" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#fff" android:orientation="vertical" > <TextView android:id="@+id/tvTitleToast" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="1dp" android:padding="1dip" android:background="#b000" android:gravity="center" android:textColor="#fff" /> <LinearLayout android:id="@+id/llToastContent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="1dip" android:layout_marginLeft="1dip" android:layout_marginRight="1dip" android:background="#4000" android:orientation="vertical" android:padding="15dip" > <ImageView android:id="@+id/tvImageToast" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:id="@+id/tvTextToast" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:paddingLeft="10dip" android:paddingRight="10dip" android:textColor="#f000" /> </LinearLayout></LinearLayout>
来源:https://www.cnblogs.com/baiqiantao/p/5690850.html