From 9c969f63ea3f197be5d0226c9f6140c90897c558 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Thu, 21 Mar 2019 11:07:42 -0700 Subject: [PATCH] For #1104 - Adds SectionedAdapter --- .../fenix/components/SectionedAdapter.kt | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 app/src/main/java/org/mozilla/fenix/components/SectionedAdapter.kt diff --git a/app/src/main/java/org/mozilla/fenix/components/SectionedAdapter.kt b/app/src/main/java/org/mozilla/fenix/components/SectionedAdapter.kt new file mode 100644 index 000000000..2d90294fb --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/SectionedAdapter.kt @@ -0,0 +1,76 @@ +package org.mozilla.fenix.components + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import java.lang.IllegalStateException + +abstract class SectionedAdapter : RecyclerView.Adapter() { + sealed class SectionType { + data class Header(val index: Int) : SectionType() + data class Row(val section: Int, val row: Int) : SectionType() + + val viewType: Int + get() = when (this) { + is Header -> HeaderViewType + is Row -> RowViewType + } + + companion object { + const val HeaderViewType = 0 + const val RowViewType = 1 + } + } + + abstract fun numberOfSections(): Int + abstract fun numberOfRowsInSection(section: Int): Int + + abstract fun onCreateHeaderViewHolder(parent: ViewGroup): RecyclerView.ViewHolder + abstract fun onBindHeaderViewHolder(holder: RecyclerView.ViewHolder, header: SectionType.Header) + abstract fun onCreateItemViewHolder(parent: ViewGroup): RecyclerView.ViewHolder + abstract fun onBindItemViewHolder(holder: RecyclerView.ViewHolder, row: SectionType.Row) + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return when (viewType) { + SectionType.HeaderViewType -> onCreateHeaderViewHolder(parent) + SectionType.RowViewType -> onCreateItemViewHolder(parent) + else -> throw IllegalStateException("ViewType: $viewType is invalid ") + } + } + + override fun getItemViewType(position: Int): Int { + return sectionTypeForPosition(position).viewType + } + + override fun getItemCount(): Int { + val numberOfSections = numberOfSections() + return numberOfSections + (0..numberOfSections).reduce { a, b -> a + numberOfRowsInSection(b) } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val sectionType = sectionTypeForPosition(position) + + when (sectionType) { + is SectionType.Header -> onBindHeaderViewHolder(holder, sectionType) + is SectionType.Row -> onBindItemViewHolder(holder, sectionType) + } + } + + private fun sectionTypeForPosition(position: Int): SectionType { + var counter = 0 + + for (section in 0..numberOfSections()) { + if (counter == position) { return SectionType.Header(section) } + counter += 1 + + for (row in 0..numberOfRowsInSection(section)) { + if (counter == position) { return SectionType.Row(section, row) } + counter += 1 + } + } + } +} \ No newline at end of file