Lists are the main way of presenting different content in mobile applications. Whether it's a social network, a book reading app or an online store, most of these apps have lists with different types of cells and different nesting levels. The clearest example known to any Android developer is the Google Play app, which has a complex start screen with many nested elements:
, 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