diff --git a/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt b/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt index b2fd76b80..752e8d086 100644 --- a/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt @@ -157,7 +157,7 @@ class ShareFragment : AppCompatDialogFragment() { val devicesShareOptions = devicesListDeferred.await() shareToAccountDevicesView.setSharetargets(devicesShareOptions) val appsToShareTo = appsListDeferred.await() - shareToAppsView.setSharetargets(appsToShareTo) + shareToAppsView.setShareTargets(appsToShareTo) } } diff --git a/app/src/main/java/org/mozilla/fenix/share/ShareToAppsView.kt b/app/src/main/java/org/mozilla/fenix/share/ShareToAppsView.kt index 84bf95d3c..7a15297fd 100644 --- a/app/src/main/java/org/mozilla/fenix/share/ShareToAppsView.kt +++ b/app/src/main/java/org/mozilla/fenix/share/ShareToAppsView.kt @@ -8,10 +8,10 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import kotlinx.android.extensions.LayoutContainer -import org.mozilla.fenix.R -import org.mozilla.fenix.share.listadapters.AppShareOption import kotlinx.android.synthetic.main.share_to_apps.* +import org.mozilla.fenix.R import org.mozilla.fenix.share.listadapters.AppShareAdapter +import org.mozilla.fenix.share.listadapters.AppShareOption /** * Callbacks for possible user interactions on the [ShareCloseView] @@ -24,19 +24,20 @@ class ShareToAppsView( override val containerView: ViewGroup, interactor: ShareToAppsInteractor ) : LayoutContainer { + + private val adapter = AppShareAdapter(interactor) + init { LayoutInflater.from(containerView.context) .inflate(R.layout.share_to_apps, containerView, true) - appsList.adapter = AppShareAdapter(interactor) + appsList.adapter = adapter } - fun setSharetargets(targets: List) { + fun setShareTargets(targets: List) { progressBar.visibility = View.GONE appsList.visibility = View.VISIBLE - with(appsList.adapter as AppShareAdapter) { - updateData(targets) - } + adapter.submitList(targets) } } diff --git a/app/src/main/java/org/mozilla/fenix/share/listadapters/AppShareAdapter.kt b/app/src/main/java/org/mozilla/fenix/share/listadapters/AppShareAdapter.kt index e2584983c..2914fc1b5 100644 --- a/app/src/main/java/org/mozilla/fenix/share/listadapters/AppShareAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/share/listadapters/AppShareAdapter.kt @@ -7,14 +7,14 @@ package org.mozilla.fenix.share.listadapters import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter import org.mozilla.fenix.share.ShareToAppsInteractor import org.mozilla.fenix.share.viewholders.AppViewHolder class AppShareAdapter( - private val interactor: ShareToAppsInteractor, - private val applications: MutableList = mutableListOf() -) : RecyclerView.Adapter() { + private val interactor: ShareToAppsInteractor +) : ListAdapter(DiffCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder { val view = LayoutInflater.from(parent.context) @@ -23,17 +23,18 @@ class AppShareAdapter( return AppViewHolder(view, interactor) } - override fun getItemCount(): Int = applications.size - override fun onBindViewHolder(holder: AppViewHolder, position: Int) { - holder.bind(applications[position]) + holder.bind(getItem(position)) } +} - fun updateData(applications: List) { - this.applications.clear() - this.applications.addAll(applications) - notifyDataSetChanged() - } +private object DiffCallback : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: AppShareOption, newItem: AppShareOption) = + oldItem.packageName == newItem.packageName + + override fun areContentsTheSame(oldItem: AppShareOption, newItem: AppShareOption) = + oldItem == newItem } data class AppShareOption( diff --git a/app/src/test/java/org/mozilla/fenix/share/listadapters/AppShareAdapterTest.kt b/app/src/test/java/org/mozilla/fenix/share/listadapters/AppShareAdapterTest.kt index 9acb9e8cf..4954b1eb0 100644 --- a/app/src/test/java/org/mozilla/fenix/share/listadapters/AppShareAdapterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/share/listadapters/AppShareAdapterTest.kt @@ -28,26 +28,25 @@ import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) @Config(application = TestApplication::class) class AppShareAdapterTest { + private val appOptions = mutableListOf( AppShareOption("App 0", mockk(), "package 0", "activity 0"), AppShareOption("App 1", mockk(), "package 1", "activity 1") ) - private val appOptionsEmpty = mutableListOf() + private val appOptionsEmpty = emptyList() private val interactor: ShareInteractor = mockk(relaxed = true) @Test - fun `updateData should replace all previous data with argument and call notifyDataSetChanged()`() { - // Used AppShareAdapter as a spy to ease testing of notifyDataSetChanged() + fun `updateData should call submitList()`() { + // Used AppShareAdapter as a spy to ease testing of submitList() // and appOptionsEmpty to be able to record them being called - val adapter = spyk(AppShareAdapter(mockk(), appOptionsEmpty)) - every { adapter.notifyDataSetChanged() } just Runs + val adapter = spyk(AppShareAdapter(mockk()).apply { submitList(appOptionsEmpty) }) + every { adapter.submitList(any()) } just Runs - adapter.updateData(appOptions) + adapter.submitList(appOptions) verifyOrder { - appOptionsEmpty.clear() - appOptionsEmpty.addAll(appOptions) - adapter.notifyDataSetChanged() + adapter.submitList(appOptions) } } @@ -60,7 +59,7 @@ class AppShareAdapterTest { @Test fun `getItemCount after updateData() call should return the the passed in list's size`() { - val adapter = AppShareAdapter(mockk(), appOptions) + val adapter = AppShareAdapter(mockk()).apply { submitList(appOptions) } assertThat(adapter.itemCount).isEqualTo(2) } @@ -89,7 +88,7 @@ class AppShareAdapterTest { @Test fun `the adapter binds the right item to a ViewHolder`() { - val adapter = AppShareAdapter(interactor, appOptions) + val adapter = AppShareAdapter(interactor).apply { submitList(appOptions) } val parentView: ViewGroup = mockk(relaxed = true) val itemView: ViewGroup = mockk(relaxed = true) every { parentView.context } returns testContext