Skip to content

Instantly share code, notes, and snippets.

@GRizzi91
Created August 4, 2021 06:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GRizzi91/55f0e0e9c65429855f2ee236075dcd51 to your computer and use it in GitHub Desktop.
Save GRizzi91/55f0e0e9c65429855f2ee236075dcd51 to your computer and use it in GitHub Desktop.
ExpandableStackView
class ExpandableStackView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr) {
fun setAdapter(adapter: BaseAdapter) {
val scene = MotionScene(this)
val startSetId = View.generateViewId()
val startSet = ConstraintSet()
startSet.clone(this)
val endSetId = View.generateViewId()
val endSet = ConstraintSet()
endSet.clone(this)
val views = mutableListOf<View>()
for (i in 0 until adapter.count) {
val view = adapter.getView(i, null, this)
val cardView = view.findViewById<CardView>(R.id.cardContainer)
view.id = View.generateViewId()
startSet.constrainHeight(view.id, ConstraintSet.WRAP_CONTENT)
endSet.constrainHeight(view.id, ConstraintSet.WRAP_CONTENT)
connectViewToParent(startSet, view)
connectViewToParent(endSet, view)
if (i == 0) {
startSet.setCardElevation(cardView, 8f)
endSet.setCardElevation(cardView, 4f)
startSet.connect(
view.id,
ConstraintSet.TOP,
ConstraintSet.PARENT_ID,
ConstraintSet.TOP
)
endSet.connect(
view.id,
ConstraintSet.TOP,
ConstraintSet.PARENT_ID,
ConstraintSet.TOP
)
} else {
if (i == 1) {
startSet.setScaleX(
view.id,
0.95f
)
startSet.setCardElevation(cardView, 6f)
endSet.setCardElevation(cardView, 4f)
} else {
startSet.setScaleX(
view.id,
0.9f
)
if (i == 2) {
startSet.setCardElevation(cardView, 4f)
endSet.setCardElevation(cardView, 4f)
} else {
startSet.setCardElevation(cardView, 0f)
endSet.setCardElevation(cardView, 4f)
}
}
views[i - 1].let {
boundTwoViewEnd(endSet, it, view)
if (i == adapter.count - 1) {
endSet.connect(
view.id,
ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID,
ConstraintSet.BOTTOM,
fromDpToPx(16).toInt()
)
}
boundTwoViewStart(
startSet, it, view,
if (i < 3)
fromDpToPx(8).toInt()
else
0
)
}
}
views.add(view)
}
views.asReversed().forEach {
addView(it)
}
val transitionId = View.generateViewId()
val transaction = TransitionBuilder.buildTransition(
scene,
transitionId,
startSetId, startSet,
endSetId, endSet
)
transaction.duration = 1000
scene.addTransition(transaction)
scene.setTransition(transaction)
setScene(scene)
setTransition(transitionId)
}
private fun boundTwoViewEnd(
constraintSet: ConstraintSet,
firstView: View,
secondView: View
) {
constraintSet.connect(
secondView.id,
ConstraintSet.TOP,
firstView.id,
ConstraintSet.BOTTOM,
fromDpToPx(16).toInt()
)
}
private fun boundTwoViewStart(
constraintSet: ConstraintSet,
firstView: View,
secondView: View,
marginBottom: Int
) {
constraintSet.connect(
secondView.id,
ConstraintSet.TOP,
firstView.id,
ConstraintSet.TOP,
marginBottom
)
}
private fun connectViewToParent(
constraintSet: ConstraintSet,
firstView: View
) {
constraintSet.connect(
firstView.id,
ConstraintSet.START,
ConstraintSet.PARENT_ID,
ConstraintSet.START
)
constraintSet.connect(
firstView.id,
ConstraintSet.END,
ConstraintSet.PARENT_ID,
ConstraintSet.END
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment