Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use WindowInsetsAnimationCompat. #3259

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package de.westnordost.streetcomplete.edithistory

import android.os.Bundle
import android.view.View
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import de.westnordost.streetcomplete.Injector
Expand Down Expand Up @@ -69,9 +70,7 @@ class EditHistoryFragment : Fragment(R.layout.fragment_edit_history_list) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

editHistoryList.respectSystemInsets { left, top, right, bottom ->
setPadding(left, top, 0, bottom)
}
editHistoryList.respectSystemInsets { updatePadding(left = it.left, top = it.top, bottom = it.bottom) }
lifecycleScope.launch {
val edits = withContext(Dispatchers.IO) { editHistorySource.getAll() }
adapter.setEdits(edits)
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/de/westnordost/streetcomplete/ktx/View.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.view.ViewGroup
import android.view.ViewPropertyAnimator
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import androidx.core.graphics.Insets
import androidx.core.os.postDelayed
import androidx.core.view.*
import kotlinx.coroutines.suspendCancellableCoroutine
Expand Down Expand Up @@ -73,6 +74,14 @@ fun View.showTapHint(initialDelay: Long = 300, pressedDelay: Long = 600) {
}
}

fun View.setPadding(insets: Insets) {
setPadding(insets.left, insets.top, insets.right, insets.bottom)
}

fun View.setMargins(insets: Insets) {
setMargins(insets.left, insets.top, insets.right, insets.bottom)
}

fun View.setMargins(left: Int, top: Int, right: Int, bottom: Int) {
updateLayoutParams<ViewGroup.MarginLayoutParams> { setMargins(left, top, right, bottom) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.UiThread
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.getSystemService
import androidx.core.graphics.Insets
import androidx.core.graphics.minus
import androidx.core.graphics.toPointF
import androidx.core.graphics.toRectF
Expand Down Expand Up @@ -96,7 +97,7 @@ class MainFragment : Fragment(R.layout.fragment_main),

private var locationWhenOpenedQuest: Location? = null

private var windowInsets: Rect? = null
private var windowInsets: Insets? = null

internal var mapFragment: QuestsMapFragment? = null
internal var mainMenuButtonFragment: MainMenuButtonFragment? = null
Expand Down Expand Up @@ -153,7 +154,7 @@ class MainFragment : Fragment(R.layout.fragment_main),
super.onViewCreated(view, savedInstanceState)

mapControls.respectSystemInsets(View::setMargins)
view.respectSystemInsets { l, t, r, b -> windowInsets = Rect(l, t, r, b) }
view.respectSystemInsets { windowInsets = it }

locationPointerPin.setOnClickListener { onClickLocationPointer() }
compassView.setOnClickListener { onClickCompassButton() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ abstract class AbstractBottomSheetFragment : Fragment(), IsCloseableBottomSheet
closeButton.setOnClickListener { activity?.onBackPressed() }

minBottomInset = Int.MAX_VALUE
view.respectSystemInsets { left, top, right, bottom ->
scrollViewChild.updatePadding(bottom = bottom)
bottomSheetContainer.updateMargins(top = top, left = left, right = right)
okButton.updateMargins(bottom = bottom + 8f.toPx(context).toInt())
view.respectSystemInsets {
scrollViewChild.updatePadding(bottom = it.bottom)
bottomSheetContainer.updateMargins(top = it.top, left = it.left, right = it.right)
okButton.updateMargins(bottom = it.bottom + 8f.toPx(context).toInt())

// expanding bottom sheet when keyboard is opened
if (minBottomInset < bottom) expand()
minBottomInset = min(bottom, minBottomInset)
if (minBottomInset < it.bottom) expand()
minBottomInset = min(it.bottom, minBottomInset)
}

bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package de.westnordost.streetcomplete.settings.questselection

import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
import android.widget.FrameLayout
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import de.westnordost.streetcomplete.HasTitle
import de.westnordost.streetcomplete.Injector
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.visiblequests.QuestPresetsController
import de.westnordost.streetcomplete.ktx.setMargins
import kotlinx.android.synthetic.main.dialog_input_text.view.*
import kotlinx.android.synthetic.main.fragment_quest_presets.view.*
import kotlinx.coroutines.Dispatchers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class TutorialFragment : Fragment(R.layout.fragment_tutorial) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

view.respectSystemInsets(View::setPadding)
view.respectSystemInsets()

updateIndicatorDots()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,54 @@
package de.westnordost.streetcomplete.view.insets_animation

import android.os.Build
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsAnimation
import androidx.annotation.RequiresApi
import androidx.core.graphics.Insets
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat
import de.westnordost.streetcomplete.ktx.setPadding

/** Make the keyboard appear and disappear smoothly. Must be set on both
* setOnApplyWindowInsetsListener and setWindowInsetsAnimationCallback */
@RequiresApi(Build.VERSION_CODES.R)
class ImeInsetsAnimationCallback(
private val view: View,
private val onNewInsets: View.(left: Int, top: Int, right: Int, bottom: Int) -> Unit
) : WindowInsetsAnimation.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE), View.OnApplyWindowInsetsListener {

private val onNewInsets: View.(insets: Insets) -> Unit
) : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE), OnApplyWindowInsetsListener {
private var isAnimating = false
private var prevInsets: WindowInsets? = null
private var prevInsets: WindowInsetsCompat? = null

override fun onApplyWindowInsets(v: View, windowInsets: WindowInsets): WindowInsets {
override fun onApplyWindowInsets(v: View, windowInsets: WindowInsetsCompat): WindowInsetsCompat {
prevInsets = windowInsets
if (!isAnimating) applyNewInsets(windowInsets)
return windowInsets
}

override fun onPrepare(animation: WindowInsetsAnimation) {
if (animation.typeMask and WindowInsets.Type.ime() != 0) {
override fun onPrepare(animation: WindowInsetsAnimationCompat) {
if (animation.typeMask and WindowInsetsCompat.Type.ime() != 0) {
isAnimating = true
}
}

override fun onProgress(insets: WindowInsets, runningAnims: List<WindowInsetsAnimation>): WindowInsets {
override fun onProgress(insets: WindowInsetsCompat, runningAnims: List<WindowInsetsAnimationCompat>): WindowInsetsCompat {
applyNewInsets(insets)
return insets
}

override fun onEnd(animation: WindowInsetsAnimation) {
if (isAnimating && (animation.typeMask and WindowInsets.Type.ime()) != 0) {
override fun onEnd(animation: WindowInsetsAnimationCompat) {
if (isAnimating && (animation.typeMask and WindowInsetsCompat.Type.ime()) != 0) {
isAnimating = false
prevInsets?.let { view.dispatchApplyWindowInsets(it) }
prevInsets?.let { view.dispatchApplyWindowInsets(it.toWindowInsets()) }
}
}

private fun applyNewInsets(insets: WindowInsets) {
val typeInsets = insets.getInsets(WindowInsets.Type.ime() or WindowInsets.Type.systemBars())
onNewInsets(view, typeInsets.left, typeInsets.top, typeInsets.right, typeInsets.bottom)
private fun applyNewInsets(insets: WindowInsetsCompat) {
val typeInsets = insets.getInsets(WindowInsetsCompat.Type.ime() or WindowInsetsCompat.Type.systemBars())
view.onNewInsets(typeInsets)
}
}

fun View.respectSystemInsets(onNewInsets: View.(left: Int, top: Int, right: Int, bottom: Int) -> Unit = View::setPadding) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val imeAnimationCallback = ImeInsetsAnimationCallback(this, onNewInsets)
setOnApplyWindowInsetsListener(imeAnimationCallback)
setWindowInsetsAnimationCallback(imeAnimationCallback)
} else {
setOnApplyWindowInsetsListener { v, windowInsets ->
onNewInsets(v,
windowInsets.systemWindowInsetLeft,
windowInsets.systemWindowInsetTop,
windowInsets.systemWindowInsetRight,
windowInsets.systemWindowInsetBottom
)
windowInsets
}
}
fun View.respectSystemInsets(onNewInsets: View.(insets: Insets) -> Unit = View::setPadding) {
val imeAnimationCallback = ImeInsetsAnimationCallback(this, onNewInsets)
ViewCompat.setOnApplyWindowInsetsListener(this, imeAnimationCallback)
ViewCompat.setWindowInsetsAnimationCallback(this, imeAnimationCallback)
}