Ejercicio: RecyclerView usando ViewBinding en Kotlin
Uso de ViewBinding en un RecyclerView en Kotlin
Tutorial sobre RecyclerView en Kotlin:
SuperHero.kt
data class SuperHero (
var superhero:String,
var publisher:String,
var realName:String,
var photo:String
)
SuperHeroProvider original
class SuperHeroProvider {
companion object {
val superHeroList = listOf<SuperHero>(
SuperHero(
"KotlinMan",
"Jetbrains",
"AristiDevs",
"https://cursokotlin.com/wp-content/uploads/2020/09/Webp.net-compress-image.jpg"
),
SuperHero(
"Spiderman",
"Marvel",
"Peter Parker",
"https://cursokotlin.com/wp-content/uploads/2017/07/spiderman.jpg"
),
SuperHero(
"Daredevil",
"Marvel",
"Matthew Michael Murdock",
"https://cursokotlin.com/wp-content/uploads/2017/07/daredevil.jpg"
),
SuperHero(
"Wolverine",
"Marvel",
"James Howlett",
"https://cursokotlin.com/wp-content/uploads/2017/07/logan.jpeg"
),
SuperHero(
"Batman",
"DC",
"Bruce Wayne",
"https://cursokotlin.com/wp-content/uploads/2017/07/batman.jpg"
),
SuperHero(
"Thor",
"Marvel",
"Thor Odinson",
"https://cursokotlin.com/wp-content/uploads/2017/07/thor.jpg"
),
SuperHero(
"Flash",
"DC",
"Jay Garrick",
"https://cursokotlin.com/wp-content/uploads/2017/07/flash.png"
),
SuperHero(
"Green Lantern",
"DC",
"Alan Scott",
"https://cursokotlin.com/wp-content/uploads/2017/07/green-lantern.jpg"
),
SuperHero(
"Wonder Woman",
"DC",
"Princess Diana",
"https://cursokotlin.com/wp-content/uploads/2017/07/wonder_woman.jpg"
)
)
}
}
SuperHeroProvider
class SuperHeroProvider {
companion object {
val URL = "https://dam.org.es/ficheros/"
val superHeroList = listOf<SuperHero>(
SuperHero(
"KotlinMan",
"Jetbrains",
"AristiDevs",
// "https://cursokotlin.com/wp-content/uploads/2020/09/Webp.net-compress-image.jpg"
URL + "Webp.net-compress-image.jpg"
),
SuperHero(
"Spiderman",
"Marvel",
"Peter Parker",
// "https://cursokotlin.com/wp-content/uploads/2017/07/spiderman.jpg"
URL + "spiderman.jpg"
),
SuperHero(
"Daredevil",
"Marvel",
"Matthew Michael Murdock",
// "https://cursokotlin.com/wp-content/uploads/2017/07/daredevil.jpg"
URL + "daredevil.jpg"
),
SuperHero(
"Wolverine",
"Marvel",
"James Howlett",
// "https://cursokotlin.com/wp-content/uploads/2017/07/logan.jpeg"
URL + "logan.jpeg"
),
SuperHero(
"Batman",
"DC",
"Bruce Wayne",
// "https://cursokotlin.com/wp-content/uploads/2017/07/batman.jpg"
URL + "batman.jpg"
),
SuperHero(
"Thor",
"Marvel",
"Thor Odinson",
// "https://cursokotlin.com/wp-content/uploads/2017/07/thor.jpg"
URL + "thor.jpg"
),
SuperHero(
"Flash",
"DC",
"Jay Garrick",
// "https://cursokotlin.com/wp-content/uploads/2017/07/flash.png"
URL + "flash.png"
),
SuperHero(
"Green Lantern",
"DC",
"Alan Scott",
// "https://cursokotlin.com/wp-content/uploads/2017/07/green-lantern.jpg"
URL + "green-lantern.jpg"
),
SuperHero(
"Wonder Woman",
"DC",
"Princess Diana",
// "https://cursokotlin.com/wp-content/uploads/2017/07/wonder_woman.jpg"
URL + "wonder_woman.jpg"
)
)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerSuperHero"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.03" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_superhero.xml
<?xml version="1.0" encoding="utf-8"?>
<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">
<ImageView
android:id="@+id/ivSuperHero"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/tvSuperHeroName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="37dp"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="@+id/ivSuperHero"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvRealName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="9dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="@+id/tvSuperHeroName"
app:layout_constraintTop_toBottomOf="@+id/tvSuperHeroName" />
<TextView
android:id="@+id/tvPublisher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/tvRealName" />
</androidx.constraintlayout.widget.ConstraintLayout>
SuperHeroViewHolder.kt
class SuperHeroViewHolder(view:View):RecyclerView.ViewHolder(view) {
val superHero = view.findViewById<TextView>(R.id.tvSuperHeroName)
val realName = view.findViewById<TextView>(R.id.tvRealName)
val publisher = view.findViewById<TextView>(R.id.tvPublisher)
val photo = view.findViewById<ImageView>(R.id.ivSuperHero)
fun render (superHeroModel: SuperHero) {
superHero.text = superHeroModel.superhero
realName.text = superHeroModel.realName
publisher.text = superHeroModel.publisher
}
}
SuperHeroAdapter.kt
class SuperHeroAdapter (val superheroList:List<SuperHero>) : RecyclerView.Adapter<SuperHeroViewHolder> () {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SuperHeroViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return SuperHeroViewHolder(layoutInflater.inflate(R.layout.item_superhero, parent, false))
}
override fun onBindViewHolder(holder: SuperHeroViewHolder, position: Int) {
val item = superheroList[position]
holder.render(item)
}
override fun getItemCount(): Int {
return superheroList.size
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initRecyclerView()
}
private fun initRecyclerView() {
val recyclerView = findViewById<RecyclerView>(R.id.recyclerSuperHero)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = SuperHeroAdapter(SuperHeroProvider.superHeroList)
}
}
Descarga de imágenes con Glide
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Dependencia en build.gradle
implementation("com.github.bumptech.glide:glide:4.16.0")
SuperHeroViewHolder.kt
class SuperHeroViewHolder(view:View):RecyclerView.ViewHolder(view) {
val superHero = view.findViewById<TextView>(R.id.tvSuperHeroName)
val realName = view.findViewById<TextView>(R.id.tvRealName)
val publisher = view.findViewById<TextView>(R.id.tvPublisher)
val photo = view.findViewById<ImageView>(R.id.ivSuperHero)
fun render (superHeroModel: SuperHero) {
superHero.text = superHeroModel.superhero
realName.text = superHeroModel.realName
publisher.text = superHeroModel.publisher
Glide.with(photo.context).load(superHeroModel.photo).into(photo)
implementation ("com.squareup.picasso:picasso:2.8")
SuperHeroViewHolder.kt
class SuperHeroViewHolder(view:View):RecyclerView.ViewHolder(view) {
val superHero = view.findViewById<TextView>(R.id.tvSuperHeroName)
val realName = view.findViewById<TextView>(R.id.tvRealName)
val publisher = view.findViewById<TextView>(R.id.tvPublisher)
val photo = view.findViewById<ImageView>(R.id.ivSuperHero)
fun render (superHeroModel: SuperHero) {
superHero.text = superHeroModel.superhero
realName.text = superHeroModel.realName
publisher.text = superHeroModel.publisher
// Glide.with(photo.context).load(superHeroModel.photo).into(photo)
Picasso.get().load(superHeroModel.photo).into(photo);
}
}
Uso de View Binding
build.gradle
buildFeatures {
viewBinding = true
}
SuperHeroViewHolder.kt
class SuperHeroViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val binding = ItemSuperheroBinding.bind(view)
fun render(superHeroModel: SuperHero, onClickListener: (SuperHero) -> Unit) {
binding.tvSuperHeroName.text = superHeroModel.superhero
binding.tvRealName.text = superHeroModel.realName
binding.tvPublisher.text = superHeroModel.publisher
// Glide.with(binding.ivSuperHero.context).load(superHeroModel.photo).into(binding.ivSuperHero)
Picasso.get().load(superHeroModel.photo).into(binding.ivSuperHero);
itemView.setOnClickListener {
onClickListener(superHeroModel)
}
}
}
SuperHeroAdapter.kt
class SuperHeroAdapter(
private val superheroList: List<SuperHero>,
private val onClickListener: (SuperHero) -> Unit
) : RecyclerView.Adapter<SuperHeroViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SuperHeroViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return SuperHeroViewHolder(layoutInflater.inflate(R.layout.item_superhero, parent, false))
}
override fun onBindViewHolder(holder: SuperHeroViewHolder, position: Int) {
val item = superheroList[position]
holder.render(item, onClickListener)
}
override fun getItemCount(): Int {
return superheroList.size
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initRecyclerView()
}
private fun initRecyclerView() {
val manager = LinearLayoutManager(this)
val decoration = DividerItemDecoration(this, manager.orientation)
binding.recyclerSuperHero.layoutManager = manager
binding.recyclerSuperHero.adapter =
SuperHeroAdapter(SuperHeroProvider.superHeroList) { superHero ->
onItemSelected(
superHero
)
}
binding.recyclerSuperHero.addItemDecoration(decoration)
}
fun onItemSelected(superHero: SuperHero) {
Toast.makeText(this, superHero.superhero, Toast.LENGTH_SHORT).show()
}
}
item_superhero.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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_marginHorizontal="16dp"
android:layout_marginVertical="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivSuperHero"
android:layout_width="150dp"
android:layout_height="150dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/tvSuperHeroName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="21sp"
android:textStyle="bold"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/ivSuperHero"
app:layout_constraintTop_toTopOf="parent"
tools:text="KotlinMan" />
<TextView
android:id="@+id/tvRealName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/ivSuperHero"
app:layout_constraintTop_toBottomOf="@+id/tvSuperHeroName"
tools:text="Julio" />
<TextView
android:id="@+id/tvPublisher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Hola" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Mejora: poner un botón que permita añadir un nuevo elemento a la lista
Más información:
How To: RecyclerView with a Kotlin-Style Click Listener in Android
Ejercicio 2 de la tarea online

Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.