首页 > 解决方案 > 运行时更改状态栏灯状态

问题描述

在我的应用程序中,我的初始屏幕和内容具有相当不同的背景 - 初始屏幕是一种较暗、统一的颜色,需要默认的浅色状态栏图标(较暗背景上的白色图标),而我的内容一直混合白色壁纸在状态栏后面,因此需要深色状态栏图标。

这可以通过使用两种不同的样式来解决,一种android:windowLightStatusBar设置为 true,另一种设置为 false。

但是,无论我做什么,我都无法获取此属性来更改状态栏的实际绘图。如果我用深色状态栏图标启动应用程序,我会一直看到深色图标,如果我选择浅色状态栏图标,我会得到那些。

我的应用程序使用单个活动架构,并且我使用了一个自定义布局充气器扩展方法,如下所示:

fun <B : ViewDataBinding> BaseFragment<*, B>.bind(
    inflater: LayoutInflater,
    @LayoutRes layout: Int,
    container: ViewGroup?,
    @StyleRes style: Int? = null,
    afterBind: () -> Unit = {}
): B =
    DataBindingUtil.inflate<B>(activity!!.getInflater(style), layout, container, false).also {
        if(style != null) activity?.setTheme(style).also { Timber.d("Theme set to ${activity?.resources?.getResourceEntryName(style)}") }
        this.binding = it
        binding.setVariable(BR.viewModel, viewModel)
        binding.lifecycleOwner = this
        afterBind()
    }

fun Context.getInflater(@StyleRes style: Int? = null): LayoutInflater =
    if(style == null)
        LayoutInflater.from(this)
    else
        LayoutInflater.from(this).changeTheme(style)

fun LayoutInflater.changeTheme(@StyleRes style: Int): LayoutInflater = cloneInContext(ContextThemeWrapper(context, style))

bind方法在BaseFragment类中使用,因此我可以使用特定布局定义我的片段,并注入适当的 ViewModel,如下所示:

abstract class BaseFragment<VM : BaseViewModel, B : ViewDataBinding>(vmClass: KClass<VM>, @LayoutRes protected val layout: Int) :
    Fragment(), KoinComponent {
    internal open lateinit var binding: B
    internal open val viewModel: VM by viewModelByClass(vmClass)

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
        bind(inflater, layout, container).root
}
class SplashFragment :
    BaseFragment<SplashViewModel, FragmentSplashBinding>(
        SplashViewModel::class,
        R.layout.fragment_splash
    ) { }

我不确定是否是我的架构搞砸了状态栏更改,或者android:windowLightStatusBar应用程序运行后是否不支持更改属性。

标签: androidkotlinandroid-themeandroid-statusbar

解决方案


推荐阅读