Refactor: change window insets handling approach
parent
a7caf9848e
commit
b27d6dbe9a
@ -0,0 +1,39 @@
|
||||
package org.koitharu.kotatsu.core.ui.util
|
||||
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.GravityInt
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import org.koitharu.kotatsu.core.util.ext.consumeRelative
|
||||
import org.koitharu.kotatsu.core.util.ext.end
|
||||
import org.koitharu.kotatsu.core.util.ext.start
|
||||
|
||||
class InsetsToMarginsListener(
|
||||
@GravityInt
|
||||
private val sides: Int,
|
||||
) : OnApplyWindowInsetsListener {
|
||||
|
||||
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
if (sides and Gravity.START == Gravity.START) marginStart = barsInsets.start(v)
|
||||
if (sides and Gravity.TOP == Gravity.TOP) topMargin = barsInsets.top
|
||||
if (sides and Gravity.END == Gravity.END) marginEnd = barsInsets.end(v)
|
||||
if (sides and Gravity.BOTTOM == Gravity.BOTTOM) bottomMargin = barsInsets.bottom
|
||||
}
|
||||
return WindowInsetsCompat.Builder(insets)
|
||||
.setInsets(
|
||||
WindowInsetsCompat.Type.systemBars(),
|
||||
barsInsets.consumeRelative(
|
||||
v,
|
||||
start = sides and Gravity.START == Gravity.START,
|
||||
top = sides and Gravity.TOP == Gravity.TOP,
|
||||
end = sides and Gravity.END == Gravity.END,
|
||||
bottom = sides and Gravity.BOTTOM == Gravity.BOTTOM,
|
||||
),
|
||||
).build()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package org.koitharu.kotatsu.core.ui.util
|
||||
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import androidx.annotation.GravityInt
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import org.koitharu.kotatsu.core.util.ext.consumeRelative
|
||||
import org.koitharu.kotatsu.core.util.ext.end
|
||||
import org.koitharu.kotatsu.core.util.ext.start
|
||||
|
||||
class InsetsToPaddingListener(
|
||||
@GravityInt
|
||||
private val sides: Int,
|
||||
) : OnApplyWindowInsetsListener {
|
||||
|
||||
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
val barsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPaddingRelative(
|
||||
/* start = */ if (sides and Gravity.START == Gravity.START) barsInsets.start(v) else v.paddingStart,
|
||||
/* top = */ if (sides and Gravity.TOP == Gravity.TOP) barsInsets.top else v.paddingTop,
|
||||
/* end = */ if (sides and Gravity.END == Gravity.END) barsInsets.end(v) else v.paddingEnd,
|
||||
/* bottom = */ if (sides and Gravity.BOTTOM == Gravity.BOTTOM) barsInsets.bottom else v.paddingBottom,
|
||||
)
|
||||
return WindowInsetsCompat.Builder(insets)
|
||||
.setInsets(
|
||||
WindowInsetsCompat.Type.systemBars(),
|
||||
barsInsets.consumeRelative(
|
||||
v,
|
||||
start = sides and Gravity.START == Gravity.START,
|
||||
top = sides and Gravity.TOP == Gravity.TOP,
|
||||
end = sides and Gravity.END == Gravity.END,
|
||||
bottom = sides and Gravity.BOTTOM == Gravity.BOTTOM,
|
||||
),
|
||||
).build()
|
||||
}
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
package org.koitharu.kotatsu.core.ui.util
|
||||
|
||||
import android.view.View
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import java.util.LinkedList
|
||||
|
||||
@Deprecated("")
|
||||
class WindowInsetsDelegate : OnApplyWindowInsetsListener, View.OnLayoutChangeListener {
|
||||
|
||||
@JvmField
|
||||
var handleImeInsets: Boolean = false
|
||||
|
||||
@JvmField
|
||||
var interceptingWindowInsetsListener: OnApplyWindowInsetsListener? = null
|
||||
|
||||
private val listeners = LinkedList<WindowInsetsListener>()
|
||||
private var lastInsets: Insets? = null
|
||||
|
||||
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
val handledInsets = interceptingWindowInsetsListener?.onApplyWindowInsets(v, insets) ?: insets
|
||||
val newInsets = if (handleImeInsets) {
|
||||
Insets.max(
|
||||
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars()),
|
||||
handledInsets.getInsets(WindowInsetsCompat.Type.ime()),
|
||||
)
|
||||
} else {
|
||||
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
}
|
||||
if (newInsets != lastInsets) {
|
||||
listeners.forEach { it.onWindowInsetsChanged(newInsets) }
|
||||
lastInsets = newInsets
|
||||
}
|
||||
return handledInsets
|
||||
}
|
||||
|
||||
override fun onLayoutChange(
|
||||
view: View,
|
||||
left: Int,
|
||||
top: Int,
|
||||
right: Int,
|
||||
bottom: Int,
|
||||
oldLeft: Int,
|
||||
oldTop: Int,
|
||||
oldRight: Int,
|
||||
oldBottom: Int,
|
||||
) {
|
||||
view.removeOnLayoutChangeListener(this)
|
||||
if (lastInsets == null) { // Listener may not be called
|
||||
onApplyWindowInsets(view, ViewCompat.getRootWindowInsets(view) ?: return)
|
||||
}
|
||||
}
|
||||
|
||||
fun addInsetsListener(listener: WindowInsetsListener) {
|
||||
listeners.add(listener)
|
||||
lastInsets?.let { listener.onWindowInsetsChanged(it) }
|
||||
}
|
||||
|
||||
fun removeInsetsListener(listener: WindowInsetsListener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun onViewCreated(view: View) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
||||
view.addOnLayoutChangeListener(this)
|
||||
}
|
||||
|
||||
fun onDestroyView() {
|
||||
lastInsets = null
|
||||
}
|
||||
|
||||
fun interface WindowInsetsListener {
|
||||
|
||||
fun onWindowInsetsChanged(insets: Insets)
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
package org.koitharu.kotatsu.details.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.transition.TransitionManager
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.OnTouchListener
|
||||
import android.view.ViewGroup
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
|
||||
import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
class TitleExpandListener(
|
||||
private val textView: SelectableTextView,
|
||||
) : GestureDetector.SimpleOnGestureListener(), OnTouchListener {
|
||||
|
||||
private val gestureDetector = GestureDetector(textView.context, this)
|
||||
private val linesExpanded = textView.resources.getInteger(R.integer.details_description_lines)
|
||||
private val linesCollapsed = textView.resources.getInteger(R.integer.details_title_lines)
|
||||
|
||||
override fun onTouch(v: View?, event: MotionEvent) = gestureDetector.onTouchEvent(event)
|
||||
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
if (textView.context.isAnimationsEnabled) {
|
||||
TransitionManager.beginDelayedTransition(textView.parent as ViewGroup)
|
||||
}
|
||||
if (textView.maxLines in 1 until Integer.MAX_VALUE) {
|
||||
textView.maxLines = Integer.MAX_VALUE
|
||||
} else {
|
||||
textView.maxLines = linesCollapsed
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onLongPress(e: MotionEvent) {
|
||||
textView.maxLines = Integer.MAX_VALUE
|
||||
textView.selectAll()
|
||||
}
|
||||
|
||||
fun attach() {
|
||||
textView.setOnTouchListener(this)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue