Skip to content

Instantly share code, notes, and snippets.

@JasonHezz
Created November 16, 2017 07:04
Show Gist options
  • Select an option

  • Save JasonHezz/c073f04c84110361171146d109fa41a5 to your computer and use it in GitHub Desktop.

Select an option

Save JasonHezz/c073f04c84110361171146d109fa41a5 to your computer and use it in GitHub Desktop.
package com.github.jasonhezz.likesplash.util
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.support.v4.view.ViewCompat
import android.support.v4.view.WindowInsetsCompat
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
/**
* Created by JavaCoder on 2017/11/14.
*/
class WindowInsetsFrameLayout @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0) : FrameLayout(context, attrs, defStyleAttr, defStyleRes) {
init {
ViewCompat.setOnApplyWindowInsetsListener(this
) { v, insets -> setWindowInsets(insets) }
}
private fun setWindowInsets(insets: WindowInsetsCompat): WindowInsetsCompat {
if (Build.VERSION.SDK_INT >= 21 && insets.hasSystemWindowInsets()) {
if (applySystemWindowInsets21(insets)) {
return insets.consumeSystemWindowInsets()
}
}
return insets
}
override protected fun fitSystemWindows(insets: Rect): Boolean {
return if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
applySystemWindowInsets19(insets)
} else super.fitSystemWindows(insets)
}
private fun applySystemWindowInsets19(insets: Rect): Boolean {
var consumed = false
for (i in 0 until childCount) {
val child = getChildAt(i)
if (!child.fitsSystemWindows) {
continue
}
val childInsets = Rect(insets)
computeInsetsWithGravity(child, childInsets)
child.setPadding(childInsets.left, childInsets.top, childInsets.right, childInsets.bottom)
consumed = true
}
return consumed
}
private fun applySystemWindowInsets21(insets: WindowInsetsCompat): Boolean {
var consumed = false
for (i in 0 until childCount) {
val child = getChildAt(i)
if (!child.fitsSystemWindows) {
continue
}
val childInsets = Rect(
insets.systemWindowInsetLeft,
insets.systemWindowInsetTop,
insets.systemWindowInsetRight,
insets.systemWindowInsetBottom)
computeInsetsWithGravity(child, childInsets)
ViewCompat.dispatchApplyWindowInsets(child, insets.replaceSystemWindowInsets(childInsets))
consumed = true
}
return consumed
}
private fun computeInsetsWithGravity(view: View, insets: Rect) {
val lp = view.getLayoutParams() as FrameLayout.LayoutParams
var gravity = lp.gravity
/**
* 因为该方法执行时机早于 FrameLayout.layoutChildren,
* 而在 {FrameLayout#layoutChildren} 中当 gravity == -1 时会设置默认值为 Gravity.TOP | Gravity.LEFT,
* 所以这里也要同样设置
*/
if (gravity == -1) {
gravity = Gravity.TOP or Gravity.START
}
if (lp.width != FrameLayout.LayoutParams.MATCH_PARENT) {
val horizontalGravity = gravity and Gravity.HORIZONTAL_GRAVITY_MASK
when (horizontalGravity) {
Gravity.START -> insets.right = 0
Gravity.END -> insets.left = 0
}
}
if (lp.height != FrameLayout.LayoutParams.MATCH_PARENT) {
val verticalGravity = gravity and Gravity.VERTICAL_GRAVITY_MASK
when (verticalGravity) {
Gravity.TOP -> insets.bottom = 0
Gravity.BOTTOM -> insets.top = 0
}
}
}
/*@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
val childCount = childCount
for (index in 0 until childCount)
getChildAt(index).dispatchApplyWindowInsets(insets)
return insets
}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment