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

如何实现类似Facebook Messenger的状态栏自定义视图(恢复应用时显示并隐藏图标)

实现类似Facebook Messenger的自定义状态栏视图效果

刚好做过类似的需求,给你拆解下Messenger这种「恢复应用时显示自定义状态栏视图、同时隐藏系统图标」的实现思路,分Android和iOS两个主流平台来说:

Android 实现步骤

1. 准备自定义状态栏布局

先创建一个XML布局(比如res/layout/custom_status_bar.xml),定义你要显示的内容,比如欢迎文字、品牌图标:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#252525"
    android:gravity="center"
    android:paddingHorizontal="16dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="欢迎回来!"
        android:textColor="#FFFFFF"
        android:textSize="14sp" />

</LinearLayout>

2. 全局监听应用前后台状态

在自定义Application类中注册ActivityLifecycleCallbacks,这样能全局捕获应用从后台回到前台的事件,避免在每个Activity中重复处理:

class MyApplication : Application() {
    private var isAppInBackground = true

    override fun onCreate() {
        super.onCreate()
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityResumed(activity: Activity) {
                if (isAppInBackground) {
                    // 从后台切回前台,触发自定义状态栏显示
                    showCustomStatusBar(activity)
                    isAppInBackground = false
                }
            }

            override fun onActivityPaused(activity: Activity) {
                isAppInBackground = true
            }

            // 其余方法空实现即可
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {}
        })
    }
}

3. 显示/隐藏自定义状态栏的核心逻辑

实现showCustomStatusBar方法,完成「添加自定义视图、隐藏系统状态栏图标、定时恢复原状」的流程:

private fun showCustomStatusBar(activity: Activity) {
    val window = activity.window
    val decorView = window.decorView as FrameLayout

    // 获取系统状态栏高度
    val statusBarHeight = run {
        val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
        if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0
    }

    // 加载自定义视图并设置布局参数
    val customView = LayoutInflater.from(this).inflate(R.layout.custom_status_bar, null)
    val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, statusBarHeight)
    params.gravity = Gravity.TOP
    customView.layoutParams = params

    // 添加到窗口的DecorView
    decorView.addView(customView)

    // 隐藏系统状态栏图标(兼容不同Android版本)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.insetsController?.hide(WindowInsets.Type.statusBars())
    } else {
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
    }

    // 3秒后移除自定义视图,恢复系统状态栏
    Handler(Looper.getMainLooper()).postDelayed({
        decorView.removeView(customView)
        // 恢复状态栏显示
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window.insetsController?.show(WindowInsets.Type.statusBars())
        } else {
            @Suppress("DEPRECATION")
            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
        }
    }, 3000) // 这里设置显示时长,单位毫秒
}

iOS 实现步骤

1. 监听应用激活事件

如果是iOS 13+的多场景应用,在SceneDelegate中监听didBecomeActive事件;如果是旧版本,在AppDelegate中监听UIApplication.didBecomeActiveNotification通知:

// iOS 13+ SceneDelegate示例
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    private var customStatusBar: UIView?

    func sceneDidBecomeActive(_ scene: UIScene) {
        // 应用从后台激活,显示自定义状态栏
        showCustomStatusBar()
    }
}

2. 实现自定义状态栏的显示逻辑

创建自定义视图,添加到窗口顶部,隐藏系统状态栏并定时恢复:

private func showCustomStatusBar() {
    guard let window = window else { return }

    // 获取状态栏高度(兼容iOS版本)
    let statusBarHeight: CGFloat
    if #available(iOS 13.0, *) {
        statusBarHeight = window.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
    } else {
        statusBarHeight = UIApplication.shared.statusBarFrame.height
    }

    // 创建自定义状态栏视图
    customStatusBar = UIView(frame: CGRect(x: 0, y: 0, width: window.bounds.width, height: statusBarHeight))
    customStatusBar?.backgroundColor = .systemBlue
    // 添加文字示例
    let welcomeLabel = UILabel(frame: customStatusBar!.bounds)
    welcomeLabel.text = "Welcome back!"
    welcomeLabel.textColor = .white
    welcomeLabel.textAlignment = .center
    customStatusBar?.addSubview(welcomeLabel)

    // 添加到窗口
    window.addSubview(customStatusBar!)

    // 隐藏系统状态栏
    if #available(iOS 13.0, *) {
        window.windowScene?.statusBarManager?.isStatusBarHidden = true
    } else {
        UIApplication.shared.isStatusBarHidden = true
    }

    // 3秒后移除视图,恢复状态栏
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
        self?.customStatusBar?.removeFromSuperview()
        self?.customStatusBar = nil
        // 恢复系统状态栏显示
        if #available(iOS 13.0, *) {
            self?.window?.windowScene?.statusBarManager?.isStatusBarHidden = false
        } else {
            UIApplication.shared.isStatusBarHidden = false
        }
    }
}

关键注意事项

  • Android适配:如果应用有多个Activity,要避免重复添加自定义视图,可以加一个全局变量标记当前是否正在显示;同时要处理深色模式、全屏页面的适配。
  • iOS适配:iOS 13+必须用SceneDelegate处理场景生命周期,否则多场景应用下事件可能不触发;另外如果你的ViewController重写了prefersStatusBarHidden,要确保恢复时的逻辑一致。
  • 交互扩展:如果需要给自定义状态栏添加点击事件,直接给视图添加UITapGestureRecognizer(iOS)或OnClickListener(Android)即可。

内容的提问来源于stack exchange,提问作者Erik Ghonyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:44:06