我的整体排查思路如下:
// 摘自 ViewGroup。
private void initViewGroup() {
// ViewGroup doesn't draw by default
if (!isShowingLayoutBounds()) {
setFlags(WILL_NOT_DRAW, DRAW_MASK);
}
.... 省略其它
}
// 摘自 NavigatorBar
init {
setWillNotDraw(false)
}
// 摘自 NavigatorBar
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// 清空画布,解决TextView.setText时,出现内容重叠的问题。
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
}
val layoutParams = WindowManager.LayoutParams()
// 设置背景透明
layoutParams.format = PixelFormat.TRANSLUCENT
/**
* @author lyf
* @date 2022/7/26 20:20
* @describe 导航栏添加类,封装WindowManager添加View的逻辑
*/
object NavigatorBarManager {
// navigatorBar显示动画
private const val animation = android.R.style.Animation_Dialog
/**
* 显示navigatorBar
* @param navigatorBar vnavigatorBar的View
*/
fun showNavigatorBar(navigatorBar: View, height: Int = 60) {
val windowManager = navigatorBar.context.getWindowManager()
val layoutParams = WindowManager.LayoutParams()
layoutParams.gravity = Gravity.BOTTOM
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
layoutParams.height = height
layoutParams.packageName = navigatorBar.context.packageName
layoutParams.y = +navigatorBar.context.resources.getDimension(R.dimen.p30).toInt()
layoutParams.windowAnimations = animation
// 设置背景透明
layoutParams.format = PixelFormat.TRANSLUCENT
// 用这个级别的level,可以不挡到toast
layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
.or(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
.or(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN)
.or(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR)
.or(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)
windowManager.addView(navigatorBar, layoutParams)
}
fun removeNavigatorBar(navigatorBar: View) {
navigatorBar.context.getWindowManager().removeView(navigatorBar)
}
private fun Context.getWindowManager() =
getSystemService(Context.WINDOW_SERVICE) as WindowManager
}
/**
* @author lyf
* @date 2022/7/26 20:20
* @describe 底部导航栏
*/
class NavigatorBar @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : FrameLayout(context, attrs) {
companion object {
private val TAG = NavigatorBar::class.java.simpleName
}
private var guideTv: TextView? = null
init {
// 自定义View,重写ViewGroup及其子类时,默认是不会去调onDraw方法。
// 加上这个,就会触发onDraw,然后,在onDraw里面,清空画布,
// 就可以解决,TextView.setText时,出现内容重叠的问题。
setWillNotDraw(false)
LayoutInflater.from(context).inflate(R.layout.layout_navigator_bar, this)
guideTv = findViewById(R.id.tv_guide)
setOnSystemUiVisibilityChangeListener {
val isFullScreen =
it.and(View.SYSTEM_UI_FLAG_FULLSCREEN) == View.SYSTEM_UI_FLAG_FULLSCREEN
val isHideNavigator =
it.and(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
visibility = if (isFullScreen || isHideNavigator) View.GONE else View.VISIBLE
Log.d(TAG, "UiVisibility=$it , isFullScreen=$isFullScreen")
}
}
fun setGuideText(guideText: String?) {
guideTv?.text = guideText.orEmpty()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// 清空画布,解决TextView.setText时,出现内容重叠的问题。
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.OVERLAY)
}
}