I wanted to create the following layout.
Layout
Main Layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Layout for Photo (home_item_image.xml
)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/draweeView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
fresco:placeholderImage="@drawable/img_placeholder_100dp"
fresco:viewAspectRatio="1"
/>
</FrameLayout>
NOTE: Using Fresco for image loading.
Layout for date header (home_item_date.xml
)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:padding="16dp"
android:id="@+id/dateTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
</FrameLayout>
RecyclerView
Activty/Fragment class variable
private lateinit var adapter: LocalAdapter
Class for RecyclerView object
sealed class ViewItem(val resource: Int) { class DateItem(val posted: LocalDateTime): ViewItem(R.layout.home_item_date) class ImageItem(val created: LocalDateTime, val uri: Uri): ViewItem(R.layout.home_item_image)}
Setup RecyclerView
// use GridLayout with 3 columnsval layoutManager = GridLayoutManager(context, 3)list.layoutManager = layoutManager// assign adapteradapter = LocalAdapter()list.adapter = adapter// expand 3 columns to single row to show datelayoutManager.spanSizeLookup = object: GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { return when (adapter.getItemViewType(position)) { R.layout.home_item_date -> 3 else -> 1 } }}
Load Data
val items = mutableListOf<ViewItem>()// dateitems.add(ViewItem.DateItem(posted = posted))// photositems.add(ViewItem.ImageItem( created = created, uri = Uri.fromFile(File(filepath))))...// date...// photos...// load items into adapteradapter.replaceItems(items)
Adapter
class LocalAdapter : RecyclerView.Adapter<LocalAdapter.ViewHolder>() { private var items = listOf<ViewItem>() override fun getItemViewType(position: Int): Int { return items[position].resource } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(viewType, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { when(val item = items[position]) { is ViewItem.DateItem -> { val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) holder.dateTextView.text = item.posted.format(formatter) } is ViewItem.ImageItem -> { holder.draweeView.setImageURI(item.uri) } } } fun replaceItems(items: List<ViewItem>) { this.items = items notifyDataSetChanged() } override fun getItemCount(): Int { return items.size } inner class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer}