A lightweight Jetpack Compose library that brings swipeable item views to your Android app — perfect for swipe-to-delete, swipe-to-edit, and any custom swipe actions in LazyColumn or standalone composables.
- Simple API — wrap any composable with
SwipeAbleItemViewand you're done. - Three swipe directions — swipe Left, Right, or Both.
- Fully customizable — control colors, widths, heights, corner radius, spacing, and icons.
- Click callbacks — receive
(position, id)pairs for each action button tap. - LazyColumn ready — works seamlessly inside infinite scrolling lists.
- Lightweight — no transitive dependencies beyond Jetpack Compose.
In your root settings.gradle.kts (or build.gradle):
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}In your app build.gradle.kts:
dependencies {
implementation("com.github.Coderkube-App:Compose-SwipeAbleView:1.0.1")
}import com.coderkube.swipeableview.SwipeAbleItemView
import com.coderkube.swipeableview.SwipeDirection
LazyColumn {
itemsIndexed(myList) { index, item ->
SwipeAbleItemView(
leftViewIcons = arrayListOf(
Triple(rememberVectorPainter(Icons.Filled.Edit), Color.White, "btnEdit"),
Triple(rememberVectorPainter(Icons.Filled.Delete), Color.White, "btnDelete")
),
rightViewIcons = arrayListOf(
Triple(rememberVectorPainter(Icons.Filled.Favorite), Color.White, "btnFavorite")
),
position = index,
swipeDirection = SwipeDirection.BOTH,
onClick = { (position, id) ->
when (id) {
"btnEdit" -> { /* handle edit */ }
"btnDelete" -> { /* handle delete */ }
"btnFavorite" -> { /* handle favorite */ }
}
},
leftViewWidth = 70.dp,
rightViewWidth = 70.dp,
height = 60.dp,
leftViewBackgroundColor = Color(0xFF6200EE),
rightViewBackgroundColor = Color(0xFF03DAC5),
cornerRadius = 8.dp,
leftSpace = 10.dp,
rightSpace = 10.dp,
fractionalThreshold = 0.3f
) {
// ↓ Your main row content goes here
MyListItemContent(item)
}
}
}SwipeAbleItemView(
leftViewIcons = arrayListOf(),
rightViewIcons = arrayListOf(
Triple(rememberVectorPainter(Icons.Filled.Delete), Color.White, "btnDelete")
),
position = index,
swipeDirection = SwipeDirection.LEFT,
onClick = { (position, _) -> viewModel.deleteItem(position) },
rightViewWidth = 80.dp,
height = 64.dp,
rightViewBackgroundColor = Color(0xFFB00020),
cornerRadius = 4.dp
) {
MyListItemContent(item)
}@Composable
fun SwipeAbleItemView(
leftViewIcons: ArrayList<Triple<Painter, Color, String>>,
rightViewIcons: ArrayList<Triple<Painter, Color, String>>,
position: Int = 0,
swipeDirection: SwipeDirection,
onClick: (Pair<Int, String>) -> Unit,
leftViewWidth: Dp = 70.dp,
rightViewWidth: Dp = 70.dp,
height: Dp = 70.dp,
leftViewBackgroundColor: Color,
rightViewBackgroundColor: Color,
cornerRadius: Dp = 0.dp,
leftSpace: Dp = 0.dp,
rightSpace: Dp = 0.dp,
fractionalThreshold: Float = 0.3f,
content: @Composable () -> Unit
)| Parameter | Type | Default | Description |
|---|---|---|---|
leftViewIcons |
ArrayList<Triple<Painter, Color, String>> |
— | Icons for the left action panel. Each Triple is (icon, tintColor, id). Shown when swiping right. |
rightViewIcons |
ArrayList<Triple<Painter, Color, String>> |
— | Icons for the right action panel. Each Triple is (icon, tintColor, id). Shown when swiping left. |
position |
Int |
0 |
Index of the item. Passed back in the onClick callback to identify the row. |
swipeDirection |
SwipeDirection |
— | Direction(s) the view can be swiped. One of LEFT, RIGHT, or BOTH. |
onClick |
(Pair<Int, String>) -> Unit |
— | Called when an action icon is tapped. Receives Pair(position, id). |
leftViewWidth |
Dp |
70.dp |
Width of the left action panel that slides in from the right side on a right-swipe. |
rightViewWidth |
Dp |
70.dp |
Width of the right action panel that slides in from the left side on a left-swipe. |
height |
Dp |
70.dp |
Height of the entire swipeable row. |
leftViewBackgroundColor |
Color |
— | Background color of the left action panel. |
rightViewBackgroundColor |
Color |
— | Background color of the right action panel. |
cornerRadius |
Dp |
0.dp |
Corner radius applied to both action panels. |
leftSpace |
Dp |
0.dp |
Gap between the left action panel and the main content. |
rightSpace |
Dp |
0.dp |
Gap between the right action panel and the main content. |
fractionalThreshold |
Float |
0.3f |
Fraction of the swipe distance (0–1) required to confirm the swipe gesture and snap to the open state. |
content |
@Composable () -> Unit |
— | The main content of the row displayed in its default (non-swiped) position. |
| Value | Behaviour |
|---|---|
SwipeDirection.LEFT |
The row can only be swiped left, revealing the right action panel. |
SwipeDirection.RIGHT |
The row can only be swiped right, revealing the left action panel. |
SwipeDirection.BOTH |
The row can be swiped in either direction, revealing the corresponding panel. |
Compose-SwipeAbleView/
├── app/ # Sample application
│ └── src/main/java/
│ └── com.coderkube.composeswipeableview/
│ ├── MainActivity.kt # Entry point; lists swipe direction demos
│ └── SwipeAbleViewActivity.kt # LazyColumn demo with SwipeAbleItemView
└── composeswipeableview/ # Library module (published to JitPack)
└── src/main/java/
└── com.coderkube.swipeableview/
├── SwipeAbleItemView.kt # Main composable
└── SwipeDirection.kt # Enum: LEFT | RIGHT | BOTH
Contributions are welcome! To get started:
- Fork this repository.
- Create a feature branch:
git checkout -b feature/my-feature. - Commit your changes:
git commit -m "feat: add my feature". - Push to your branch:
git push origin feature/my-feature. - Open a Pull Request against the
mainbranch.
Please make sure your code follows the existing Kotlin style and that the sample app runs correctly before submitting.
Copyright 2026 Coderkube-App
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
See the full LICENSE file for details.