其他
Github上最好用的Android状态栏导航栏库
https://juejin.cn/user/1275089219488526/posts
https://github.com/Zackratos/UltimateBarX
https://blog.csdn.net/guolin_blog/article/details/51763825
window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
val flag = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
window?.decorView?.systemUiVisibility = flag
window?.statusBarColor = Color.TRANSPARENT
window?.navigationBarColor = Color.TRANSPARENT
}
window?.statusBarColor = Color.RED
window?.navigationBarColor = Color.RED
}
window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
val decorView = window?.decorView as FrameLayout?
val contentView = decorView?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
contentView?.fitsSystemWindows = true
val statusBarView = View(this)
statusBarView.setBackgroundColor(Color.RED)
val statusBarLP = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight())
statusBarLP.gravity = Gravity.TOP
decorView?.addView(statusBarView, statusBarLP)
val navigationBarView = View(this)
navigationBarView.setBackgroundColor(Color.RED)
val navigationBarLP = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getNavigationBarHeight())
navigationBarLP.gravity = Gravity.BOTTOM
decorView?.addView(navigationBarView, navigationBarLP)
}
statusBarFitWindow: Boolean,
@ColorInt statusBarColor: Int,
navigationBarFitWindow: Boolean,
@ColorInt navigationBarColor: Int
) {
transparentBar()
setStatusBarView(statusBarFitWindow, statusBarColor)
setNavigationBarView(navigationBarFitWindow, navigationBarColor)
}
private fun transparentBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val flag = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
window?.decorView?.systemUiVisibility = flag
window?.statusBarColor = Color.TRANSPARENT
window?.navigationBarColor = Color.TRANSPARENT
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window?.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
val decorView = window?.decorView as FrameLayout?
val contentView = decorView?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
contentView?.fitsSystemWindows = false
decorView?.clipToPadding = false
}
private fun setStatusBarView(statusBarFitWindow: Boolean, @ColorInt statusBarColor: Int) {
val decorView = window?.decorView as FrameLayout?
var statusBarView = decorView?.findViewWithTag<View>("status_bar")
if (statusBarView == null) {
statusBarView = View(this)
statusBarView.tag = "status_bar"
}
statusBarView.setBackgroundColor(statusBarColor)
val statusBarLP =
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight())
if (statusBarFitWindow) {
statusBarLP.topMargin = -getStatusBarHeight()
decorView?.setPadding(0, getStatusBarHeight(), 0, decorView.paddingBottom)
} else {
statusBarLP.topMargin = 0
decorView?.setPadding(0, 0, 0, decorView.paddingBottom)
}
statusBarLP.gravity = Gravity.TOP
decorView?.addView(statusBarView, statusBarLP)
}
private fun setNavigationBarView(navigationBarFitWindow: Boolean, @ColorInt navigationBarColor: Int) {
val decorView = window?.decorView as FrameLayout?
var navigationBarView = decorView?.findViewWithTag<View>("navigation_bar")
if (navigationBarView == null) {
navigationBarView = View(this)
navigationBarView.tag = "navigation_bar"
}
navigationBarView.setBackgroundColor(navigationBarColor)
val navigationBarLP =
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getNavigationBarHeight())
if (navigationBarFitWindow) {
navigationBarLP.bottomMargin = -getNavigationBarHeight()
decorView?.setPadding(0, decorView.paddingTop, 0, getNavigationBarHeight())
} else {
navigationBarLP.bottomMargin = 0
decorView?.setPadding(0, decorView.paddingTop, 0, 0)
}
navigationBarLP.gravity = Gravity.BOTTOM
decorView?.addView(navigationBarView, navigationBarLP)
}
val flag = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
window?.decorView?.systemUiVisibility = flag
window?.statusBarColor = Color.TRANSPARENT
window?.navigationBarColor = Color.TRANSPARENT
}
private fun systemUiFlag(statusBarLight: Boolean, navigationBarLight: Boolean): Int {
var flag = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
if (statusBarLight) flag = flag or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
if (navigationBarLight) flag = flag or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
if (statusBarLight) flag = flag or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
}
return flag
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy(owner: LifecycleOwner) {
UltimateBarXManager.getInstance().removeAllData(owner)
}
}
private fun test() {
addObserver(UltimateBarXObserver())
}
val navigationBarColor = window?.navigationBarColor ?: Color.TRANSPARENT
originColorMap[this] = navigationBarColor
val navConfig = getNavigationBarConfig(this)
navConfig.light = calculateLight(navigationBarColor)
putNavigationBarConfig(this, navConfig)
}
private fun calculateLight(@ColorInt color: Int) = color > (Color.BLACK + Color.WHITE / 2)
val rootView = requireView() as RelativeLayout
var statusBarView = rootView.findViewWithTag<View>("status_bar")
if (statusBarView == null) {
statusBarView = View(requireContext())
statusBarView.tag = "status_bar"
}
statusBarView.setBackgroundColor(statusBarColor)
val statusBarLP =
RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight())
if (statusBarFitWindow) {
statusBarLP.topMargin = -getStatusBarHeight()
rootView.setPadding(0, getStatusBarHeight(), 0, rootView.paddingBottom)
} else {
statusBarLP.topMargin = 0
rootView.setPadding(0, 0, 0, rootView.paddingBottom)
}
statusBarLP.addRule(RelativeLayout.ALIGN_PARENT_TOP)
rootView.addView(statusBarView, statusBarLP)
}
private fun setNavigationBarView(navigationBarFitWindow: Boolean, @ColorInt navigationBarColor: Int) {
val rootView = requireView() as RelativeLayout
var navigationBarView = rootView.findViewWithTag<View>("navigation_bar")
if (navigationBarView == null) {
navigationBarView = View(requireContext())
navigationBarView.tag = "navigation_bar"
}
navigationBarView.setBackgroundColor(navigationBarColor)
val navigationBarLP =
RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getNavigationBarHeight())
if (navigationBarFitWindow) {
navigationBarLP.bottomMargin = -getNavigationBarHeight()
rootView.setPadding(0, rootView.paddingTop, 0, getNavigationBarHeight())
} else {
navigationBarLP.bottomMargin = 0
rootView.setPadding(0, rootView.paddingTop, 0, 0)
}
navigationBarLP.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
rootView.addView(navigationBarView, navigationBarLP)
}
val rootView = requireView() as ViewGroup
val paddingTop = if (statusBarFitWindow) getStatusBarHeight() else 0
rootView.setPadding(0, paddingTop, 0, rootView.paddingBottom)
var statusBarView = rootView.findViewWithTag<View>("status_bar")
if (statusBarView == null) {
statusBarView = View(requireContext())
statusBarView.tag = "status_bar"
}
statusBarView.setBackgroundColor(statusBarColor)
rootView.addView(statusBarView, ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight())
statusBarView.post { statusBarView.translationY = -statusBarView.top.toFloat() }
}
private fun setNavigationBarView(navigationBarFitWindow: Boolean, @ColorInt navigationBarColor: Int) {
val rootView = requireView() as ViewGroup
val paddingBottom = if (navigationBarFitWindow) getNavigationBarHeight() else 0
rootView.setPadding(0, rootView.paddingTop, 0, paddingBottom)
var navigationBarView = rootView.findViewWithTag<View>("navigation_bar")
if (navigationBarView == null) {
navigationBarView = View(requireContext())
navigationBarView.tag = "navigation_bar"
}
navigationBarView.setBackgroundColor(navigationBarColor)
rootView.addView(navigationBarView, ViewGroup.LayoutParams.MATCH_PARENT, getNavigationBarHeight())
navigationBarView.post { navigationBarView.translationY = (rootView.height - navigationBarView.bottom).toFloat() }
}
val view = requireView()
if (view is FrameLayout || view is RelativeLayout) return view as ViewGroup
val flWrapper = FrameLayout(requireContext())
flWrapper.setTag(androidx.fragment.R.id.fragment_container_view_tag, this)
val parent = view.parent
if (parent is ViewGroup) {
val index = parent.indexOfChild(view)
parent.removeViewAt(index)
parent.addView(flWrapper, index)
}
flWrapper.addView(view)
val fragmentViewFiled = Fragment::class.java.getDeclaredField("mView")
fragmentViewFiled.isAccessible = true
fragmentViewFiled.set(this, flWrapper)
return flWrapper
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy(owner: LifecycleOwner) {
UltimateBarXManager.getInstance().removeAllData(owner)
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onResume(owner: LifecycleOwner) {
if (owner is Fragment) {
val staDefault = UltimateBarXManager.getInstance().getStatusBarDefault(owner)
val navDefault = UltimateBarXManager.getInstance().getNavigationBarDefault(owner)
if (staDefault) {
UltimateBarX.get(owner).applyStatusBar()
}
if (navDefault) {
UltimateBarX.get(owner).applyNavigationBar()
}
}
}
}
状态栏和导航栏彻底解藕,单独设置,互不影响 同一个 Activity 或 Fragment 可以多次设置不同的效果
UltimateBarX.with(this) // 在当前 Activity/Fragment 生效
.fitWindow(true) // 是否侵入状态栏 (true: 不侵入)
.color(Color.BLACK) // 状态栏颜色(色值)
.colorRes(R.color.deepSkyBlue) // 状态栏颜色(资源 id)
.drawableRes(R.drawable.bg_gradient) // 状态栏背景(drawable 资源)
.light(false) // light 模式(true: 字体变灰)
.applyStatusBar() // 应用到状态栏
}