Skip to content

Instantly share code, notes, and snippets.

@JakeSteam
Last active January 28, 2019 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakeSteam/97a827d4d7ccced73fed798025f61ea1 to your computer and use it in GitHub Desktop.
Save JakeSteam/97a827d4d7ccced73fed798025f61ea1 to your computer and use it in GitHub Desktop.
"Creating a RecyclerView with multiple content types and layouts in Kotlin" @ https://blog.jakelee.co.uk/creating-a-recyclerview-with-multiple-content-types-and-layouts-in-kotlin
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
class ContentAdapter(private val rows: List<IRow>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
interface IRow
class HeaderRow(val date: String, val title: String) : IRow
class MessageRow(val message: String) : IRow
class ColourRow(val colour: Int) : IRow
class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val dateView: TextView = itemView.findViewById(R.id.date)
val titleView: TextView = itemView.findViewById(R.id.title)
}
class MessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val messageView: TextView = itemView.findViewById(R.id.message)
}
class ColourViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val colourView: ImageView = itemView.findViewById(R.id.colour)
}
override fun getItemCount() = rows.count()
override fun getItemViewType(position: Int): Int =
when (rows[position]) {
is HeaderRow -> TYPE_HEADER
is MessageRow -> TYPE_MESSAGE
is ColourRow -> TYPE_COLOUR
else -> throw IllegalArgumentException()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
TYPE_HEADER -> HeaderViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.row_header, parent, false))
TYPE_MESSAGE -> MessageViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.row_message, parent, false))
TYPE_COLOUR -> ColourViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.row_colour, parent, false))
else -> throw IllegalArgumentException()
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
when (holder.itemViewType) {
TYPE_HEADER -> onBindHeader(holder, rows[position] as ContentAdapter.HeaderRow)
TYPE_MESSAGE -> onBindMessage(holder, rows[position] as ContentAdapter.MessageRow)
TYPE_COLOUR -> onBindColour(holder, rows[position] as ContentAdapter.ColourRow)
else -> throw IllegalArgumentException()
}
private fun onBindHeader(holder: RecyclerView.ViewHolder, row: HeaderRow) {
val headerRow = holder as HeaderViewHolder
headerRow.titleView.text = row.title
headerRow.dateView.text = row.date
}
private fun onBindMessage(holder: RecyclerView.ViewHolder, row: MessageRow) {
(holder as MessageViewHolder).messageView.text = row.message
}
private fun onBindColour(holder: RecyclerView.ViewHolder, row: ColourRow) {
(holder as ColourViewHolder).colourView.setBackgroundColor(row.colour)
}
companion object {
private const val TYPE_HEADER = 0
private const val TYPE_MESSAGE = 1
private const val TYPE_COLOUR = 2
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView.adapter = ContentAdapter(getSampleRows(10))
recyclerView.layoutManager = LinearLayoutManager(this)
}
private fun getSampleRows(numSections: Int): List<ContentAdapter.IRow> {
val rows = mutableListOf<ContentAdapter.IRow>()
for (i in 1..numSections) {
rows.add(ContentAdapter.HeaderRow(Randomiser.date(), Randomiser.word()))
val numChildren = Randomiser.int(0, 10)
for (j in 1..numChildren) {
if(Randomiser.int(0, 1) > 0) {
rows.add(ContentAdapter.MessageRow(Randomiser.message()))
} else {
rows.add(ContentAdapter.ColourRow(Randomiser.colour()))
}
}
}
return rows
}
}
class Randomiser {
companion object {
fun int(min: Int, max: Int): Int {
return (min..max).shuffled().last()
}
fun date(): String {
val calendar = Calendar.getInstance()
calendar.add(Calendar.DAY_OF_YEAR, -int(0, 1000))
val format = SimpleDateFormat("dd/MM/yyyy", Locale.UK)
return format.format(calendar.time)
}
fun word() = ('a'..'z').map { it }.shuffled().subList(0, 8).joinToString("").capitalize()
fun message() = UUID.randomUUID().toString()
fun colour(): Int {
val rnd = Random()
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))
}
}
}
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/colour"
android:layout_height="50dp"
android:layout_width="match_parent" />
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/black">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingStart="10dp"
android:textColor="@android:color/white"
android:textSize="18sp"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/title"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1.0"
android:paddingEnd="10dp"
android:textColor="@android:color/white"
android:textSize="18sp"/>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment