Frequently asked questions and solutions.
See Getting Started for the installation guide.
CardStackView supports Android API Level 21 (Android 5.0) and higher.
Yes, CardStackView is fully compatible with Java, even though it's written in Kotlin.
You can enable/disable swipes at runtime:
// Disable
manager.setSwipeableMethod(SwipeableMethod.None)
manager.setCanScrollHorizontal(false)
manager.setCanScrollVertical(false)
// Enable
manager.setSwipeableMethod(SwipeableMethod.AutomaticAndManual)
manager.setCanScrollHorizontal(true)
manager.setCanScrollVertical(true)See also: Issue #381
You can use a custom listener and enable/disable swipes in the callbacks:
lateinit var manager: CardStackLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
manager = CardStackLayoutManager(this, object : CardStackListener {
override fun onCardDragging(direction: Direction?, ratio: Float) {}
override fun onCardSwiped(direction: Direction?) {}
override fun onCardRewound() {}
override fun onCardCanceled() {}
override fun onCardAppeared(view: View?, position: Int) {}
override fun onCardDisappeared(view: View?, position: Int) {}
})
cardStackView.layoutManager = manager
}
private fun setupButtons() {
val disable = findViewById<View>(R.id.disable_swipe_button)
val enable = findViewById<View>(R.id.enable_swipe_button)
disable.setOnClickListener {
manager.setSwipeableMethod(SwipeableMethod.None)
manager.setCanScrollHorizontal(false)
manager.setCanScrollVertical(false)
}
enable.setOnClickListener {
manager.setSwipeableMethod(SwipeableMethod.AutomaticAndManual)
manager.setCanScrollHorizontal(true)
manager.setCanScrollVertical(true)
}
}// Only to the right
manager.setDirections(listOf(Direction.Right))
manager.setCanScrollLeft(false)
manager.setCanScrollRight(true)
// Only to the left
manager.setDirections(listOf(Direction.Left))
manager.setCanScrollLeft(true)
manager.setCanScrollRight(false)Check the following:
-
IDs are correct: IDs must be exact:
left_overlayright_overlaytop_overlaybottom_overlay
-
Visibility is visible: Overlay containers must have
visibility="visible":android:visibility="visible"
-
Directions are enabled: Overlays only react to enabled directions:
// If only Direction.Left is enabled, right_overlay will never appear manager.setDirections(listOf(Direction.Left))
-
Manager instance is reused: Make sure you use the same manager instance:
val manager = CardStackLayoutManager(context, listener).apply { setDirections(Direction.HORIZONTAL) setOverlayInterpolator(LinearInterpolator()) } cardStackView.layoutManager = manager
-
Alpha is not set manually: Let the library control alpha values.
See also: Overlay Troubleshooting and Issue #383
Use setOverlayInterpolator():
manager.setOverlayInterpolator(LinearInterpolator()) // Linear
manager.setOverlayInterpolator(AccelerateInterpolator()) // Accelerating
manager.setOverlayInterpolator(DecelerateInterpolator()) // DeceleratingSee Paging Guide for a complete guide.
Important: Do not use notifyDataSetChanged() for paging, as this resets the topPosition.
For paging: No. Use DiffUtil or notifyItemRangeInserted() instead.
For reloading: Yes, notifyDataSetChanged() is fine for complete reloading.
Implement CardStackListener and load data when the user approaches the end:
override fun onCardSwiped(direction: Direction?) {
val currentPosition = manager.topPosition
val totalItems = adapter.itemCount
if (currentPosition >= totalItems - 5) {
loadMoreData()
}
}Adjust the swipeThreshold:
manager.setSwipeThreshold(0.1f) // Very sensitive (10%)
manager.setSwipeThreshold(0.3f) // Default (30%)
manager.setSwipeThreshold(0.5f) // Less sensitive (50%)Set maxDegree to 0:
manager.setMaxDegree(0.0f)Use setTranslationInterval():
manager.setTranslationInterval(4.0f) // Tight
manager.setTranslationInterval(8.0f) // Default
manager.setTranslationInterval(12.0f) // WideSet scaleInterval to 1.0f:
manager.setScaleInterval(1.0f)val setting = SwipeAnimationSetting.Builder()
.setDirection(Direction.Right)
.setDuration(Duration.Normal.duration)
.setInterpolator(AccelerateInterpolator())
.build()
manager.setSwipeAnimationSetting(setting)See Custom Animations for more details.
Set the duration to 0:
manager.setLastItemAppearingAnimationDuration(0)manager.setDirections(Direction.VERTICAL)
manager.setManualRewindDirections(listOf(Direction.Bottom))Important: manualRewindDirections must not contain any directions that are already enabled in setDirections().
This happens when a direction is enabled in both setDirections() and setManualRewindDirections():
// ❌ ERROR
manager.setDirections(listOf(Direction.Left, Direction.Right))
manager.setManualRewindDirections(listOf(Direction.Left)) // IllegalArgumentException!
// ✅ CORRECT
manager.setDirections(Direction.HORIZONTAL) // Left, Right
manager.setManualRewindDirections(listOf(Direction.Bottom)) // Bottom for rewindval carousel = CarouselSetting(
orientation = CarouselOrientation.Horizontal,
scaleMultiplier = 0.18f,
minScale = 0.65f,
tiltAngle = 8f
)
manager.setStackStyle(CardStackStyle.Carousel)
manager.setCarouselSetting(carousel)
manager.setStackFrom(StackFrom.Bottom)
manager.setTranslationInterval(16f)See Advanced Features for more details.
- Use DiffUtil: For paging and updates
- Avoid heavy operations in onCardDragging: Called very frequently
- Use ViewHolder pattern: Properly implemented in adapter
- Avoid too many simultaneous animations
- Check if the adapter has data
- Check if
layoutManageris set - Check the layout parameters of CardStackView
Avoid notifyDataSetChanged() for paging. Use DiffUtil or notifyItemRangeInserted() instead.
- Check
setSwipeableMethod()- is it set toNone? - Check
setCanScrollHorizontal()/setCanScrollVertical() - Check
setDirections()- are directions enabled?
- Getting Started - First steps
- Configuration - All options
- Guides - Detailed guides
- API Reference - Complete API documentation
If you have further questions, please open an issue on GitHub.