标题有点拗口,其实是可以分别写成两篇博文的。也就是说看完这篇能了解两个方面:

  • 自定义布局样式的Toast

  • 自定义PopupWindow实现多功能Toast

先感性认识:

Android 用自定义PopupWindow实现自定义Toast_第1张图片

触发事件来自于MenuItem的onClick,具体请看上一篇Android 自定义Menu


一 、自定义布局样式的Toast

布局文件dialog_toast.xml



    
    

使用这个自定义布局,解决多次Toast重复弹出。

/**
 * 显示自定义Toast

* private Toast mToast;
* View toastView = mLayoutInflater.inflate(R.layout.dialog_toast, null); * @param toastView */ private void showToast(View toastView) { toastView.setBackgroundColor(Color.TRANSPARENT); if (mToast == null) { mToast = new Toast(mContext); mToast.setView(toastView); mToast.setGravity(Gravity.BOTTOM|Gravity.CENTER, 0, 100); mToast.setDuration(Toast.LENGTH_SHORT); } mToast.show(); }


二 、自定义PopupWindow实现多功能Toast

以下是MenuItem点击事件的完整代码,详细注释了。

@Override
public void onClick(View v) {
    /** MenuItem dismiss */
    mPopWindow.dismiss();
    /**
     * 自定义PopupWindow模拟多功能Toast
     */
    View popToastView = mLayoutInflater.inflate(
            R.layout.dialog_toast, null);
    mPopToast = new PopupWindow(popToastView,
            LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT, true);
    mPopToast.setBackgroundDrawable(new ColorDrawable(
            Color.TRANSPARENT));
    mPopWindow.setOutsideTouchable(true);// 设置触摸外面时消失
    mPopToast
            .setAnimationStyle(android.R.style.Animation_Dialog);// 设置动画效果
    mPopToast.showAtLocation(v,
            Gravity.BOTTOM | Gravity.CENTER, 0, 300);
    /**
     * 用PopupWindow模拟Toast,里面的TextView的点击事件。
     * 因为Toast不获取焦点,所以View的事件无法处理。
     * 而PopupWindow解决了这个焦点问题。
     */
    TextView dialogContent = (TextView) popToastView
            .findViewById(R.id.dialog_content);
    dialogContent.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mPopToast != null && mPopToast.isShowing()) {
                mPopToast.dismiss();
                /** 再次显示自定义Toast, 这次是从PopupWindow里面的TextView触发的 */
                View toastViewAgain = mLayoutInflater.inflate(
                        R.layout.dialog_toast, null);
                showToast(toastViewAgain);
            }
        }
    });
    /** 显示自定义Toast */
    View toastView = mLayoutInflater.inflate(
            R.layout.dialog_toast, null);
    showToast(toastView);
}

使用PopupWindow实现的Toast可以不受Toast.LENGTH_SHORT或Toast.LENGTH_LONG的时间限制,并且可以得到焦点和用户交互,比如onClick等等。


Toast本身是一个非常便捷的提示组件,它的特点就是使用便捷,比如

Toast.makeText(mContext, "123", Toast.LENGTH_SHORT).show();

这样的一句代码就可以给出用户一个很友好的提示。

如果想做出复杂的交互功能,这些就不是Toast的定位了,需要自定义PopupWindow或者AlertDialog来实现,它们的定位在此。