You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11及以上替代Toast.setGravity()实现居中类Toast提示的方案?

Android 11+ 实现屏幕居中类Toast消息的解决方案

从Android 11(API 30)开始,系统原生Toast的setGravity()方法已被废弃,自定义位置的逻辑不会生效,因此要实现居中显示的类Toast消息,需要放弃原生Toast,使用自定义实现即可,以下两种方案均可以实现和原生Toast一致的轻量反馈效果:

方案1:轻量自定义类Toast实现(推荐,最接近原生体验)

该方案无额外依赖,不抢占界面焦点,和原生Toast行为完全一致,支持自定义显示位置、样式、时长:

  • 核心逻辑通过应用内WindowManager添加悬浮提示View实现,不需要申请悬浮窗权限,通过Handler实现到时间自动隐藏
    示例Kotlin代码如下:
class CustomToast private constructor(private val context: Context) {
    private var windowManager: WindowManager? = null
    private var toastView: View? = null
    private val handler = Handler(Looper.getMainLooper())

    companion object {
        const val LENGTH_SHORT = 2000L
        const val LENGTH_LONG = 3500L

        fun makeText(context: Context, message: String, duration: Long = LENGTH_SHORT): CustomToast {
            val toast = CustomToast(context)
            // 加载自定义布局,可根据需求修改样式
            toast.toastView = LayoutInflater.from(context).inflate(R.layout.layout_custom_toast, null).apply {
                findViewById<TextView>(R.id.tv_toast_msg).text = message
            }
            toast.windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
            return toast
        }
    }

    fun show() {
        toastView ?: return
        windowManager ?: return
        val params = WindowManager.LayoutParams().apply {
            height = WindowManager.LayoutParams.WRAP_CONTENT
            width = WindowManager.LayoutParams.WRAP_CONTENT
            format = PixelFormat.TRANSLUCENT
            // 设置不抢占焦点、不接收触摸事件,和原生Toast行为一致
            flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            gravity = Gravity.CENTER // 这里直接设置居中,可修改为任意位置
            type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                WindowManager.LayoutParams.TYPE_TOAST
            }
        }
        windowManager?.addView(toastView, params)
        // 到时间自动移除
        handler.postDelayed({ cancel() }, duration)
    }

    fun cancel() {
        try {
            if (toastView?.isAttachedToWindow == true) {
                windowManager?.removeView(toastView)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        toastView = null
        windowManager = null
    }
}
  • 配套布局文件layout_custom_toast.xml可根据需求自定义,示例如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_toast"
    android:paddingHorizontal="16dp"
    android:paddingVertical="12dp"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tv_toast_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:textSize="14sp"/>
</LinearLayout>
  • 调用方式和原生Toast完全一致:
CustomToast.makeText(this, "居中显示的提示消息", CustomToast.LENGTH_SHORT).show()

方案2:透明Dialog模拟(实现更简单)

如果不需要复杂的全局显示逻辑,仅在单个页面内使用,用透明Dialog实现更快捷:

  • 自定义Dialog样式,设置背景透明、无标题、不可点击取消,布局和上述自定义Toast布局一致即可
  • 通过Handler.postDelayed()实现到时间自动关闭,示例代码:
fun showCenterToast(context: Context, msg: String, duration: Long = 2000L) {
    val dialog = Dialog(context)
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
    dialog.setContentView(R.layout.layout_custom_toast)
    dialog.findViewById<TextView>(R.id.tv_toast_msg).text = msg
    dialog.window?.apply {
        setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        val params = attributes
        params.gravity = Gravity.CENTER
        attributes = params
    }
    dialog.setCancelable(false)
    dialog.show()
    Handler(Looper.getMainLooper()).postDelayed({
        if (dialog.isShowing) dialog.dismiss()
    }, duration)
}

两种方案均支持完全自定义样式,灵活度远高于原生Toast,且不会受系统版本限制,在所有Android版本上均可实现居中显示效果。

内容的提问来源于stack exchange,提问作者Allan Antony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:39:04