Is there any special way to create recyclerView in Compose Jetpack? Or it is the same as usual?
How to create recycler view in Compose Jetpack?
12.7k views Asked by Nurseyit Tursunkulov AtThere are 7 answers
In jetnews
sample project for list/recyclerview
they are using VerticalScroller
with Column
and using forEach
to populate items below @Composable
function is example
@Composable
private fun TabWithTopics(tabname: String, topics: List<String>) {
VerticalScroller {
Column {
HeightSpacer(16.dp)
topics.forEach { topic ->
TopicItem(
getTopicKey(
tabname,
"- ",
topic
), topic
)
TopicDivider()
}
}
}
}
For class and method check this link
For more information you can download/clone jetnews
sample from check here's link
https://github.com/android/compose-samples/tree/master/JetNews
For latest Jetpack alpha release update the below:
@Composable
fun LazyRowItemsDemo() {
LazyRowFor(items = (1..1000).toList()) {
Text(text = "Item $it")
}
}
- LazyColumnFor for a vertical list
- LazyRowFor for a horizontal list
Hope it's helpful for you.
Examples from JetNews app have static data. It's worth to mention that according to the recent Google presentation (see especially from 18:30), we should consider ScrollingList
, which is intended for list with undefined number of elements (e.g. downloaded from the web), what was traditionally handled by RecyclerView
. Then, it should look like this:
@Composable
fun NewsFeed(stories: List<StoryData>) {
ScrollingList(stories) { story ->
StoryWidget(story)
}
}
or we can do similar thing with LiveData
or RxJava Observable
/Flowable
:
@Composable
fun NewsFeed(stories: LiveData<List<StoryData>>) {
ScrollingList(stories.observe()) { story ->
StoryWidget(story)
}
}
In such case, we are re-using StoryWidget
(or any other widget of our choice) in the every step of the iteration with data emitted dynamically through the lambda expression.
According to this article there is new version:
@Composable
fun <T> AdapterList(
data: List<T>,
modifier: Modifier = Modifier.None,
itemCallback: @Composable() (T) -> Unit
)
@Composable
fun Scrollable(
dragDirection: DragDirection,
scrollableState: ScrollableState,
onScrollStarted: (startedPosition: PxPosition) -> Unit = {},
onScrollStopped: (velocity: Float) -> Unit = {},
enabled: Boolean = true,
children: @Composable() () -> Unit
)
AdapterList(
data = (1..20).map { it }.toList()
) {
if (it % 2 == 0) {
Text("$it Even", style = TextStyle(fontSize = 40.sp, color =
Color.Gray))
} else {
Text(text = "$it Odd", style = TextStyle(fontSize = 70.sp))
}
}
UPDATED and current implementation at dev06 Jetpack Compose uses AdapterList
and you could use the simple example included by Nurseyit Tursunkulov and I can share a more complex (real case scenario use):
- Your
List<Any>
must be "compose aware" and the current one available for that isModelList<Any>
- You can create a model using
@Model
tag as those change the state, and your@Compososable
function will be aware (using aMutableList
)
Example Code:
fun addLogic(modelList: ModelList<MyModel>) {
modelList.add(MyModel("Smith John", 10))
}
class MyModel(var name: String, var index: Int)
@Composable
fun RecycledList() { // Any name you want
val modelList<MyModel> = modelListOf()
var counter = 0
addLogic(modelList)
modelList.add(MyModel("John Doe", 99))
MaterialTheme {
Column {
Container(height = 70.dp) {
Align(alignment = Alignment.Center) {
Button(onClick = {
modelList.add(MyModel("John Smith", counter++))
// Any other logic you want
}) {
Text("ADD ITEM")
}
}
}
AdapterList(data = modelList) { item ->
Center {
Text("Hello ${item.name} - Index: ${item.index}")
}
},
}
}
}
Result:
Update March 2021: Starting from
1.0.0-beta01
LazyColumn
for a vertical listLazyRow
for a horizontal listFor example: