As listas são a principal forma de apresentar diferentes conteúdos em aplicativos móveis. Seja uma rede social, um aplicativo de leitura de livros ou uma loja online, a maioria desses aplicativos possui listas com diferentes tipos de células, diferentes níveis de aninhamento. O exemplo mais claro conhecido por qualquer desenvolvedor Android é o aplicativo Google Play, que tem uma tela inicial complexa com muitos elementos aninhados:

, RecyclerView. , , 20 , .
:
, : , , . ? , , , .
, , — RecyclerView , RecyclerView . , adapter , ViewHolders . Groupie
Groupie is a simple, flexible library for complex RecyclerView layouts.
RecyclerView, .
, , Android MergeAdapter ( , ). , . , , , - SOLID.
, :
- . .
- . layouts UI
- RecyclerView .
.
4 : RecyclerView, CardView, Picasso ( ) Groupie. build.gradle(app):
implementation 'com.xwray:groupie:2.8.0'
implementation 'com.xwray:groupie-kotlin-android-extensions:2.8.0'
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'androidx.cardview:cardview:1.0.0'
, build.gradle android
androidExtensions {
experimental = true
}
Sync Now .
3 :
- — . .
- . . RecyclerView c .
- . .
RecyclerView
RecyclerView .
CardView LinearLayout , RecyclerView .
<?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:id="@+id/main_content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="#FFFFFF"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="vertical">
<TextView
android:id="@+id/title_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:textSize="18sp"
android:textStyle="bold"
tools:text=" " />
<TextView
android:id="@+id/description_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textSize="12sp"
tools:text=" " />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/items_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="16dp"
android:orientation="horizontal"
android:visibility="visible"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:ignore="RtlSymmetry" />
</LinearLayout>
</androidx.cardview.widget.CardView>
.
class MainCardContainer(
private val title: String? = "",
private val description: String? = "",
private val onClick: (url: String) -> Unit,
private val items: List<Item>
) : Item() {
override fun getLayout() = R.layout.item_card
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
viewHolder.title_text_view.text = title
viewHolder.description_text_view.text = description
viewHolder.items_container.adapter =
GroupAdapter<GroupieViewHolder>().apply { addAll(items) }
}
}
Groupie Item. 2 getLayout() bind(). layout UI ! , SOLID. , , . C Groupie , UI!
, , Item, , RecyclerView. , :
viewHolder.items_container.adapter =
GroupAdapter<GroupieViewHolder>().apply { addAll(items) }
RecyclerView , GroupAdapter , Item.
, .
2:
, Item 2 :
class MovieItem(private val content: MovieContent) : Item() {
override fun getLayout() = R.layout.item_with_text
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
viewHolder.description.text = content.title
Picasso.get()
.load(content.url)
.into(viewHolder.image_preview)
}
}
GitHub.
, .
.
RecyclerView. 2 getPopularMovies() getPopularGames() Item.
private fun getPopularMovies(): Item {
return MainCardContainer(
" ", " ", ::onItemClick,
listOf(
MovieItem(
MovieContent(
"",
"https://upload.wikimedia.....jpg"
)
),
MovieItem(
MovieContent(
" ",
"https://upload.wikimedia.org......jpg"
)
)
)
)
}
1 MainCardContainer — RecyclerView. , MovieItem. , — , .
:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val movies = listOf(getPopularMovies(), getPopularGames())
items_container.adapter =
GroupAdapter<GroupieViewHolder>().apply { addAll(movies) }
}
GroupAdapter , Item.
! 20 ! ! , UI — . - @android_school_ru Kotlin - Android-.
GitHub