Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
Move adapter Job setup code to helper class (#3407)
Browse files Browse the repository at this point in the history
  • Loading branch information
NotWoods authored and colintheshots committed Jul 1, 2019
1 parent eb1ea88 commit 8cd1a0c
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ import mozilla.components.browser.icons.IconRequest
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.sessioncontrol.Tab
import org.mozilla.fenix.utils.AdapterWithJob
import kotlin.coroutines.CoroutineContext

class CollectionCreationTabListAdapter(
val actionEmitter: Observer<CollectionCreationAction>
) : RecyclerView.Adapter<TabViewHolder>() {
) : AdapterWithJob<TabViewHolder>() {
private var tabs: List<Tab> = listOf()
private var selectedTabs: MutableSet<Tab> = mutableSetOf()
private lateinit var job: Job
private var hideCheckboxes = false

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(TabViewHolder.LAYOUT_ID, parent, false)

return TabViewHolder(view, job)
return TabViewHolder(view, adapterJob)
}

override fun onBindViewHolder(holder: TabViewHolder, position: Int, payloads: MutableList<Any>) {
Expand Down Expand Up @@ -73,16 +73,6 @@ class CollectionCreationTabListAdapter(

override fun getItemCount(): Int = tabs.size

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}

fun updateData(tabs: List<Tab>, selectedTabs: Set<Tab>, hideCheckboxes: Boolean = false) {
val diffUtil = DiffUtil.calculateDiff(
TabDiffUtil(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.components.description
import org.mozilla.fenix.home.sessioncontrol.Tab
import org.mozilla.fenix.home.sessioncontrol.TabCollection
import org.mozilla.fenix.utils.AdapterWithJob
import kotlin.coroutines.CoroutineContext

class SaveCollectionListAdapter(
val actionEmitter: Observer<CollectionCreationAction>
) : RecyclerView.Adapter<CollectionViewHolder>() {
) : AdapterWithJob<CollectionViewHolder>() {

private lateinit var job: Job
private var tabCollections = listOf<TabCollection>()
private var selectedTabs: Set<Tab> = setOf()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CollectionViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(CollectionViewHolder.LAYOUT_ID, parent, false)

return CollectionViewHolder(view, actionEmitter, job)
return CollectionViewHolder(view, actionEmitter, adapterJob)
}

override fun onBindViewHolder(holder: CollectionViewHolder, position: Int) {
Expand All @@ -49,16 +49,6 @@ class SaveCollectionListAdapter(

override fun getItemCount(): Int = tabCollections.size

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}

fun updateData(tabCollections: List<TabCollection>, selectedTabs: Set<Tab>) {
this.tabCollections = tabCollections
this.selectedTabs = selectedTabs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer
import kotlinx.coroutines.Job
import org.mozilla.fenix.exceptions.viewholders.ExceptionsDeleteButtonViewHolder
import org.mozilla.fenix.exceptions.viewholders.ExceptionsHeaderViewHolder
import org.mozilla.fenix.exceptions.viewholders.ExceptionsListItemViewHolder
import org.mozilla.fenix.utils.AdapterWithJob

private sealed class AdapterItem {
object DeleteButton : AdapterItem()
Expand All @@ -34,9 +34,8 @@ private class ExceptionsList(val exceptions: List<ExceptionsItem>) {

class ExceptionsAdapter(
private val actionEmitter: Observer<ExceptionsAction>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
) : AdapterWithJob<RecyclerView.ViewHolder>() {
private var exceptionsList: ExceptionsList = ExceptionsList(emptyList())
private lateinit var job: Job

fun updateData(items: List<ExceptionsItem>) {
this.exceptionsList = ExceptionsList(items)
Expand All @@ -59,7 +58,7 @@ class ExceptionsAdapter(
return when (viewType) {
ExceptionsDeleteButtonViewHolder.LAYOUT_ID -> ExceptionsDeleteButtonViewHolder(view, actionEmitter)
ExceptionsHeaderViewHolder.LAYOUT_ID -> ExceptionsHeaderViewHolder(view)
ExceptionsListItemViewHolder.LAYOUT_ID -> ExceptionsListItemViewHolder(view, actionEmitter, job)
ExceptionsListItemViewHolder.LAYOUT_ID -> ExceptionsListItemViewHolder(view, actionEmitter, adapterJob)
else -> throw IllegalStateException()
}
}
Expand All @@ -71,14 +70,4 @@ class ExceptionsAdapter(
}
}
}

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer
import kotlinx.coroutines.Job
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.NoContentMessageViewHolder
Expand All @@ -31,6 +29,7 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPr
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingSectionHeaderViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingThemePickerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder
import org.mozilla.fenix.utils.ListAdapterWithJob
import mozilla.components.feature.tab.collections.Tab as ComponentTab

sealed class AdapterItem(@LayoutRes val viewType: Int) {
Expand Down Expand Up @@ -92,23 +91,21 @@ class AdapterItemDiffCallback : DiffUtil.ItemCallback<AdapterItem>() {

class SessionControlAdapter(
private val actionEmitter: Observer<SessionControlAction>
) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) {

private lateinit var job: Job
) : ListAdapterWithJob<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) {

// This method triggers the ComplexMethod lint error when in fact it's quite simple.
@SuppressWarnings("ComplexMethod")
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
return when (viewType) {
TabHeaderViewHolder.LAYOUT_ID -> TabHeaderViewHolder(view, actionEmitter)
TabViewHolder.LAYOUT_ID -> TabViewHolder(view, actionEmitter, job)
TabViewHolder.LAYOUT_ID -> TabViewHolder(view, actionEmitter, adapterJob)
SaveTabGroupViewHolder.LAYOUT_ID -> SaveTabGroupViewHolder(view, actionEmitter)
PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(view, actionEmitter)
NoContentMessageViewHolder.LAYOUT_ID -> NoContentMessageViewHolder(view)
CollectionHeaderViewHolder.LAYOUT_ID -> CollectionHeaderViewHolder(view)
CollectionViewHolder.LAYOUT_ID -> CollectionViewHolder(view, actionEmitter, job)
TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, actionEmitter, job)
CollectionViewHolder.LAYOUT_ID -> CollectionViewHolder(view, actionEmitter, adapterJob)
TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, actionEmitter, adapterJob)
OnboardingHeaderViewHolder.LAYOUT_ID -> OnboardingHeaderViewHolder(view)
OnboardingSectionHeaderViewHolder.LAYOUT_ID -> OnboardingSectionHeaderViewHolder(view)
OnboardingFirefoxAccountViewHolder.LAYOUT_ID -> OnboardingFirefoxAccountViewHolder(view)
Expand All @@ -121,16 +118,6 @@ class SessionControlAdapter(
}
}

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}

override fun getItemViewType(position: Int) = getItem(position).viewType

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.ThemeManager
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.utils.AdapterWithJob
import kotlin.coroutines.CoroutineContext

class BookmarkAdapter(val emptyView: View, val actionEmitter: Observer<BookmarkAction>) :
RecyclerView.Adapter<BookmarkAdapter.BookmarkNodeViewHolder>() {
AdapterWithJob<BookmarkAdapter.BookmarkNodeViewHolder>() {

private var tree: List<BookmarkNode> = listOf()
private var mode: BookmarkState.Mode = BookmarkState.Mode.Normal
val selected: Set<BookmarkNode>
get() = (mode as? BookmarkState.Mode.Selecting)?.selectedItems ?: setOf()
private var isFirstRun = true

lateinit var job: Job

fun updateData(tree: BookmarkNode?, mode: BookmarkState.Mode) {
this.tree = tree?.children ?: listOf()
isFirstRun = if (isFirstRun) false else {
Expand All @@ -54,13 +53,13 @@ class BookmarkAdapter(val emptyView: View, val actionEmitter: Observer<BookmarkA

return when (viewType) {
BookmarkItemViewHolder.viewType.ordinal -> BookmarkItemViewHolder(
view, actionEmitter, job
view, actionEmitter, adapterJob
)
BookmarkFolderViewHolder.viewType.ordinal -> BookmarkFolderViewHolder(
view, actionEmitter, job
view, actionEmitter, adapterJob
)
BookmarkSeparatorViewHolder.viewType.ordinal -> BookmarkSeparatorViewHolder(
view, actionEmitter, job
view, actionEmitter, adapterJob
)
else -> throw IllegalStateException("ViewType $viewType does not match to a ViewHolder")
}
Expand All @@ -75,16 +74,6 @@ class BookmarkAdapter(val emptyView: View, val actionEmitter: Observer<BookmarkA
}
}

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}

override fun getItemCount(): Int = tree.size

override fun onBindViewHolder(holder: BookmarkNodeViewHolder, position: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer
import kotlinx.coroutines.Job
import org.mozilla.fenix.R
import org.mozilla.fenix.library.history.viewholders.HistoryDeleteButtonViewHolder
import org.mozilla.fenix.library.history.viewholders.HistoryHeaderViewHolder
import org.mozilla.fenix.library.history.viewholders.HistoryListItemViewHolder
import java.lang.IllegalStateException
import java.util.Date
import org.mozilla.fenix.utils.AdapterWithJob
import java.util.Calendar
import java.util.Date

private sealed class AdapterItem {
object DeleteButton : AdapterItem()
Expand Down Expand Up @@ -96,10 +95,9 @@ private class HistoryList(val history: List<HistoryItem>) {

class HistoryAdapter(
private val actionEmitter: Observer<HistoryAction>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
) : AdapterWithJob<RecyclerView.ViewHolder>() {
private var historyList: HistoryList = HistoryList(emptyList())
private var mode: HistoryState.Mode = HistoryState.Mode.Normal
private lateinit var job: Job
var selected = listOf<HistoryItem>()

fun updateData(items: List<HistoryItem>, mode: HistoryState.Mode) {
Expand All @@ -126,7 +124,7 @@ class HistoryAdapter(
return when (viewType) {
HistoryDeleteButtonViewHolder.LAYOUT_ID -> HistoryDeleteButtonViewHolder(view, actionEmitter)
HistoryHeaderViewHolder.LAYOUT_ID -> HistoryHeaderViewHolder(view)
HistoryListItemViewHolder.LAYOUT_ID -> HistoryListItemViewHolder(view, actionEmitter, job)
HistoryListItemViewHolder.LAYOUT_ID -> HistoryListItemViewHolder(view, actionEmitter, adapterJob)
else -> throw IllegalStateException()
}
}
Expand All @@ -144,14 +142,4 @@ class HistoryAdapter(
}
}
}

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}
}
17 changes: 3 additions & 14 deletions app/src/main/java/org/mozilla/fenix/share/AppShareView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import io.reactivex.Observer
import kotlinx.android.synthetic.main.app_share_list_item.view.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.mozilla.fenix.R
import org.mozilla.fenix.utils.AdapterWithJob
import kotlin.coroutines.CoroutineContext

class AppShareRecyclerView @JvmOverloads constructor(
Expand All @@ -40,11 +40,10 @@ class AppShareAdapter(
private val context: Context,
val actionEmitter: Observer<ShareAction>,
private val intentType: String = "text/plain"
) : RecyclerView.Adapter<AppShareItemViewHolder>(), CoroutineScope {
) : AdapterWithJob<AppShareItemViewHolder>(), CoroutineScope {

private var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
get() = Dispatchers.IO + adapterJob
private var size: Int = 0
private val shareItems: MutableList<ShareItem> = mutableListOf()

Expand Down Expand Up @@ -87,16 +86,6 @@ class AppShareAdapter(
override fun onBindViewHolder(holder: AppShareItemViewHolder, position: Int) {
holder.bind(shareItems[position])
}

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
job = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
job.cancel()
}
}

class AppShareItemViewHolder(
Expand Down
48 changes: 48 additions & 0 deletions app/src/main/java/org/mozilla/fenix/utils/AdapterWithJob.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.mozilla.fenix.utils

import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Job

/* 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/. */

/**
* [RecyclerView.Adapter] with a [Job] for coroutines.
* The adapterJob is setup when the adapter is attached to a RecyclerView and canceled when detached.
*/
abstract class AdapterWithJob<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() {
protected lateinit var adapterJob: Job

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
adapterJob = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
adapterJob.cancel()
}
}

/**
* [ListAdapter] with a [Job] for coroutines.
* The adapterJob is setup when the adapter is attached to a RecyclerView and canceled when detached.
*/
abstract class ListAdapterWithJob<T, VH : RecyclerView.ViewHolder>(
diffCallback: DiffUtil.ItemCallback<T>
) : ListAdapter<T, VH>(diffCallback) {
protected lateinit var adapterJob: Job

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
adapterJob = Job()
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
adapterJob.cancel()
}
}

0 comments on commit 8cd1a0c

Please sign in to comment.