horizontal expand/collapse

This commit is contained in:
InsanusMokrassar 2020-12-15 13:25:01 +06:00
parent 1890608cb3
commit 830b7aee56
2 changed files with 90 additions and 22 deletions

View File

@ -2,6 +2,10 @@
## 0.4.13 ## 0.4.13
* `Common`
* `Android`
* Add expand/collapse functionality for horizontal expand/collapse
## 0.4.12 ## 0.4.12
* `Coroutines` * `Coroutines`

View File

@ -5,23 +5,44 @@ import android.view.ViewGroup
import android.view.animation.Animation import android.view.animation.Animation
import android.view.animation.Transformation import android.view.animation.Transformation
@PreviewFeature private fun View.performExpand(
fun View.expand(
duration: Long = 500, duration: Long = 500,
targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT, targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT,
targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
onMeasured: View.() -> Unit,
onPerformAnimation: View.(interpolatedTime: Float, t: Transformation?) -> Unit
) { ) {
measure(targetWidth, targetHeight) measure(targetWidth, targetHeight)
val measuredHeight: Int = measuredHeight onMeasured()
layoutParams.height = 0
visibility = View.VISIBLE visibility = View.VISIBLE
val a: Animation = object : Animation() { val a: Animation = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
super.applyTransformation(interpolatedTime, t) super.applyTransformation(interpolatedTime, t)
layoutParams.height = if (interpolatedTime == 1f) targetHeight else (measuredHeight * interpolatedTime).toInt() onPerformAnimation(interpolatedTime, t)
requestLayout() requestLayout()
} }
override fun willChangeBounds(): Boolean = true
}
a.duration = duration
startAnimation(a)
}
private fun View.performCollapse(
duration: Long = 500,
onPerformAnimation: View.(interpolatedTime: Float, t: Transformation?) -> Unit
) {
val a: Animation = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
if (interpolatedTime == 1f) {
gone()
} else {
onPerformAnimation(interpolatedTime, t)
requestLayout()
}
}
override fun willChangeBounds(): Boolean { override fun willChangeBounds(): Boolean {
return true return true
} }
@ -32,27 +53,58 @@ fun View.expand(
startAnimation(a) startAnimation(a)
} }
@PreviewFeature
fun View.expand(
duration: Long = 500,
targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT,
targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT
) {
var measuredHeight = 0
performExpand(
duration,
targetWidth,
targetHeight,
{
measuredHeight = this.measuredHeight
}
) { interpolatedTime, _ ->
layoutParams.height = if (interpolatedTime == 1f) targetHeight else (measuredHeight * interpolatedTime).toInt()
}
}
@PreviewFeature
fun View.expandHorizontally(
duration: Long = 500,
targetWidth: Int = ViewGroup.LayoutParams.MATCH_PARENT,
targetHeight: Int = ViewGroup.LayoutParams.WRAP_CONTENT
) {
var measuredWidth = 0
performExpand(
duration,
targetWidth,
targetHeight,
{
measuredWidth = this.measuredWidth
}
) { interpolatedTime, _ ->
layoutParams.width = if (interpolatedTime == 1f) targetWidth else (measuredWidth * interpolatedTime).toInt()
}
}
@PreviewFeature @PreviewFeature
fun View.collapse(duration: Long = 500) { fun View.collapse(duration: Long = 500) {
val initialHeight: Int = measuredHeight val initialHeight: Int = measuredHeight
val a: Animation = object : Animation() { performCollapse(duration) { interpolatedTime, _ ->
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) { layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
if (interpolatedTime == 1f) {
visibility = View.GONE
} else {
layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
requestLayout()
}
}
override fun willChangeBounds(): Boolean {
return true
}
} }
}
a.duration = duration @PreviewFeature
fun View.collapseHorizontally(duration: Long = 500) {
startAnimation(a) val initialWidth: Int = measuredWidth
performCollapse(duration) { interpolatedTime, _ ->
layoutParams.width = initialWidth - (initialWidth * interpolatedTime).toInt()
}
} }
@PreviewFeature @PreviewFeature
@ -74,3 +126,15 @@ fun View.toggleExpandState(duration: Long = 500): Boolean = if (isCollapsed) {
collapse(duration) collapse(duration)
false false
} }
/**
* @return true in case of expanding
*/
@PreviewFeature
fun View.toggleExpandHorizontallyState(duration: Long = 500): Boolean = if (isCollapsed) {
expandHorizontally(duration)
true
} else {
collapseHorizontally(duration)
false
}