ListView
ViewHolder
patternLayoutManager
defines direction
RecyclerView
delegates the presentation of items to the corresponding Adapter
Adapter
interface<?xml version="1.0" encoding="utf-8"?>
<!-- activity_main3.xml -->
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<?xml version="1.0" encoding="utf-8"?>
<!-- list_item_view.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/item_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/item_number" />
</androidx.constraintlayout.widget.ConstraintLayout>
ViewHolder
RecyclerView
Adapter
cache expensive View.findViewById(int)
resultsRecyclerView.Adapter
package de.hdmstuttgart.manifestdemo;
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity(), MovieClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.list)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
val list: MutableList<DummyItem> = ArrayList<DummyItem>()
for (i in 0..100) {
list.add(DummyItem(i.toString(), " - "))
}
val adapter = MovieAdapter(data)
recyclerView.adapter = adapter
}
class DummyItem(var id: String, var content: String)
class MovieAdapter(private val list: List<DummyItem>, private val movieClickListener: MovieClickListener): RecyclerView.Adapter<MovieAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.movie_view, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val dummyItemModel = list[position]
holder.itemNumberView.text = dummyItemModel.id
holder.contentView.text = dummyItemModel.content
}
override fun getItemCount(): Int {
return list.size
}
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val itemNumberView: TextView = itemView.findViewById(R.id.item_number)
val contentView: TextView = itemView.findViewById(R.id.content)
}
}
}
LazyColumn
and LazyRow
follows the same patterns as RecyclerView
but makes it much easier in Jetpack Compose@Composable
. They provide a LazyListScope
block in order to describe the item contents.Check the following example:
@Composable
fun MovieList(modifier: Modifier = Modifier) {
val movieList = remember {
mutableStateListOf<Movie>(
//Movie objects
)
}
LazyColumn(modifier = modifier) {
items(items = movieList) { movie: Movie ->
MovieItem(movie = movie, onMovieClick = { currentMovie: Movie ->
movieList.remove(currentMovie)
})
}
}
}