diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/CheckInsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/CheckInsFragment.kt index d03a3c9ff7dc681122b5b97a5c916f9d6650dc46..488b48271452b4ac0e7012fb90a267387ea46d21 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/CheckInsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/CheckInsFragment.kt @@ -26,8 +26,7 @@ import de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.items.CameraPer import de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.items.CheckInsItem import de.rki.coronawarnapp.ui.presencetracing.attendee.edit.EditCheckInFragmentArgs import de.rki.coronawarnapp.util.di.AutoInject -import de.rki.coronawarnapp.util.list.isSwipeable -import de.rki.coronawarnapp.util.list.onSwipeItem +import de.rki.coronawarnapp.util.list.setupSwipe import de.rki.coronawarnapp.util.lists.decorations.TopBottomPaddingDecorator import de.rki.coronawarnapp.util.lists.diffutil.update import de.rki.coronawarnapp.util.onScroll @@ -190,14 +189,7 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag } } - onSwipeItem( - context = requireContext(), - ) { position, direction -> - val checkInsItem = checkInsAdapter.data[position] - if (checkInsItem.isSwipeable()) { - checkInsItem.onSwipe(position, direction) - } - } + setupSwipe(context = requireContext()) } } @@ -211,11 +203,8 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag setPositiveButton(R.string.generic_action_remove) { _, _ -> viewModel.onRemoveCheckInConfirmed(checkIn) } - setNegativeButton(R.string.generic_action_abort) { _, _ -> - position?.let { checkInsAdapter.notifyItemChanged(position) } - } - - setOnCancelListener { + setNegativeButton(R.string.generic_action_abort) { _, _ -> } + setOnDismissListener { position?.let { checkInsAdapter.notifyItemChanged(position) } } }.show() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/ActiveCheckInVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/ActiveCheckInVH.kt index 40af15182ecb798da9abffe633a558a51c13ba02..2ce414b1d3750b342259a51b8eb7bf45c9181857 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/ActiveCheckInVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/ActiveCheckInVH.kt @@ -1,12 +1,13 @@ package de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.items import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView import de.rki.coronawarnapp.R import de.rki.coronawarnapp.contactdiary.util.getLocale import de.rki.coronawarnapp.databinding.TraceLocationAttendeeCheckinsItemActiveBinding import de.rki.coronawarnapp.presencetracing.checkins.CheckIn import de.rki.coronawarnapp.util.TimeAndDateExtensions.toUserTimeZone -import de.rki.coronawarnapp.util.list.SwipeConsumer +import de.rki.coronawarnapp.util.list.Swipeable import de.rki.coronawarnapp.util.lists.diffutil.HasPayloadDiffer import org.joda.time.Duration import org.joda.time.DurationFieldType @@ -20,7 +21,14 @@ class ActiveCheckInVH(parent: ViewGroup) : BaseCheckInVH<ActiveCheckInVH.Item, TraceLocationAttendeeCheckinsItemActiveBinding>( layoutRes = R.layout.trace_location_attendee_checkins_item_active, parent = parent - ) { + ), + Swipeable { + + private var latestItem: Item? = null + + override fun onSwipe(holder: RecyclerView.ViewHolder, direction: Int) { + latestItem?.let { it.onSwipeItem(it.checkin, holder.adapterPosition) } + } override val viewBinding: Lazy<TraceLocationAttendeeCheckinsItemActiveBinding> = lazy { TraceLocationAttendeeCheckinsItemActiveBinding.bind(itemView) @@ -35,6 +43,7 @@ class ActiveCheckInVH(parent: ViewGroup) : payloads: List<Any> ) -> Unit = { item, payloads -> val curItem = payloads.filterIsInstance<Item>().singleOrNull() ?: item + latestItem = curItem val checkInStartUserTZ = curItem.checkin.checkInStart.toUserTimeZone() @@ -93,12 +102,10 @@ class ActiveCheckInVH(parent: ViewGroup) : val onRemoveItem: (CheckIn) -> Unit, val onCheckout: (CheckIn) -> Unit, val onSwipeItem: (CheckIn, Int) -> Unit, - ) : CheckInsItem, HasPayloadDiffer, SwipeConsumer { + ) : CheckInsItem, HasPayloadDiffer { override val stableId: Long = checkin.id override fun diffPayload(old: Any, new: Any): Any? = if (old::class == new::class) new else null - - override fun onSwipe(position: Int, direction: Int) = onSwipeItem(checkin, position) } companion object { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/CameraPermissionVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/CameraPermissionVH.kt index 43d63e51f42d128ae92b3c135c45692a2dfde6ac..c0dd87bca11e3fa56ea0debb73223530043d023c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/CameraPermissionVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/CameraPermissionVH.kt @@ -3,14 +3,12 @@ package de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.items import android.view.ViewGroup import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.TraceLocationAttendeeCheckinsItemCameraBinding -import de.rki.coronawarnapp.util.list.Movable class CameraPermissionVH(parent: ViewGroup) : BaseCheckInVH<CameraPermissionVH.Item, TraceLocationAttendeeCheckinsItemCameraBinding>( layoutRes = R.layout.trace_location_attendee_checkins_item_camera, parent = parent - ), - Movable { + ) { override val viewBinding: Lazy<TraceLocationAttendeeCheckinsItemCameraBinding> = lazy { TraceLocationAttendeeCheckinsItemCameraBinding.bind(itemView) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/PastCheckInVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/PastCheckInVH.kt index 106b09f13341fddceb6265d968b8ab136b5ef922..67f8c43637de037742c57b5a894451b7f119659d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/PastCheckInVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/attendee/checkins/items/PastCheckInVH.kt @@ -1,18 +1,26 @@ package de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.items import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.TraceLocationAttendeeCheckinsItemPastBinding import de.rki.coronawarnapp.presencetracing.checkins.CheckIn import de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.common.checkoutInfo -import de.rki.coronawarnapp.util.list.SwipeConsumer +import de.rki.coronawarnapp.util.list.Swipeable import de.rki.coronawarnapp.util.lists.diffutil.HasPayloadDiffer class PastCheckInVH(parent: ViewGroup) : BaseCheckInVH<PastCheckInVH.Item, TraceLocationAttendeeCheckinsItemPastBinding>( layoutRes = R.layout.trace_location_attendee_checkins_item_past, parent = parent - ) { + ), + Swipeable { + + private var latestItem: Item? = null + + override fun onSwipe(holder: RecyclerView.ViewHolder, direction: Int) { + latestItem?.let { it.onSwipeItem(it.checkin, holder.adapterPosition) } + } override val viewBinding: Lazy<TraceLocationAttendeeCheckinsItemPastBinding> = lazy { TraceLocationAttendeeCheckinsItemPastBinding.bind(itemView) @@ -23,6 +31,8 @@ class PastCheckInVH(parent: ViewGroup) : payloads: List<Any> ) -> Unit = { item, payloads -> val curItem = payloads.filterIsInstance<Item>().singleOrNull() ?: item + latestItem = curItem + description.text = curItem.checkin.description address.text = curItem.checkin.address @@ -46,11 +56,9 @@ class PastCheckInVH(parent: ViewGroup) : val onCardClicked: (CheckIn, Int) -> Unit, val onRemoveItem: (CheckIn) -> Unit, val onSwipeItem: (CheckIn, Int) -> Unit, - ) : CheckInsItem, HasPayloadDiffer, SwipeConsumer { + ) : CheckInsItem, HasPayloadDiffer { override val stableId: Long = checkin.id override fun diffPayload(old: Any, new: Any): Any? = if (old::class == new::class) new else null - - override fun onSwipe(position: Int, direction: Int) = onSwipeItem(checkin, position) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/TraceLocationsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/TraceLocationsFragment.kt index 3c20d506d92f5ea94b0adb6d00928b4078485ad9..ad212665966570326dbd4de14ac6b43da6fb138f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/TraceLocationsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/TraceLocationsFragment.kt @@ -20,8 +20,7 @@ import de.rki.coronawarnapp.ui.presencetracing.organizer.category.adapter.catego import de.rki.coronawarnapp.ui.presencetracing.organizer.details.QrCodeDetailFragmentArgs import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.di.AutoInject -import de.rki.coronawarnapp.util.list.isSwipeable -import de.rki.coronawarnapp.util.list.onSwipeItem +import de.rki.coronawarnapp.util.list.setupSwipe import de.rki.coronawarnapp.util.lists.decorations.TopBottomPaddingDecorator import de.rki.coronawarnapp.util.lists.diffutil.update import de.rki.coronawarnapp.util.onScroll @@ -58,12 +57,7 @@ class TraceLocationsFragment : Fragment(R.layout.trace_location_organizer_trace_ onScroll { onScrollChange(it) } - onSwipeItem(context = requireContext()) { position, direction -> - val traceLocationItem = traceLocationsAdapter.data[position] - if (traceLocationItem.isSwipeable()) { - traceLocationItem.onSwipe(position, direction) - } - } + setupSwipe(context = requireContext()) } binding.toolbar.setNavigationOnClickListener { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/items/TraceLocationVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/items/TraceLocationVH.kt index 8b1504fc242d79535e301a185a80fdaa9afd9c1e..a2a24e88483fcbb9e10c74824de1985ef1301118 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/items/TraceLocationVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/presencetracing/organizer/list/items/TraceLocationVH.kt @@ -3,19 +3,27 @@ package de.rki.coronawarnapp.ui.presencetracing.organizer.list.items import android.view.ViewGroup import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.recyclerview.widget.RecyclerView import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.TraceLocationOrganizerTraceLocationsItemBinding import de.rki.coronawarnapp.presencetracing.checkins.qrcode.TraceLocation import de.rki.coronawarnapp.ui.presencetracing.attendee.checkins.items.BaseCheckInVH.Companion.setupMenu import de.rki.coronawarnapp.ui.presencetracing.organizer.list.TraceLocationsAdapter -import de.rki.coronawarnapp.util.list.SwipeConsumer +import de.rki.coronawarnapp.util.list.Swipeable import org.joda.time.format.DateTimeFormat class TraceLocationVH(parent: ViewGroup) : TraceLocationsAdapter.ItemVH<TraceLocationVH.Item, TraceLocationOrganizerTraceLocationsItemBinding>( layoutRes = R.layout.trace_location_organizer_trace_locations_item, parent = parent - ) { + ), + Swipeable { + + private var latestItem: Item? = null + + override fun onSwipe(holder: RecyclerView.ViewHolder, direction: Int) { + latestItem?.let { it.onSwipeItem(it.traceLocation, holder.adapterPosition) } + } override val viewBinding: Lazy<TraceLocationOrganizerTraceLocationsItemBinding> = lazy { TraceLocationOrganizerTraceLocationsItemBinding.bind(itemView) @@ -25,6 +33,7 @@ class TraceLocationVH(parent: ViewGroup) : item: Item, payloads: List<Any> ) -> Unit = { item, _ -> + latestItem = item description.text = item.traceLocation.description address.text = item.traceLocation.address @@ -84,8 +93,7 @@ class TraceLocationVH(parent: ViewGroup) : val onDeleteItem: (TraceLocation) -> Unit, val onSwipeItem: (TraceLocation, Int) -> Unit, val onCardClicked: (TraceLocation, Int) -> Unit - ) : TraceLocationItem, SwipeConsumer { + ) : TraceLocationItem { override val stableId: Long = traceLocation.id.hashCode().toLong() - override fun onSwipe(position: Int, direction: Int) = onSwipeItem(traceLocation, position) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeConsumer.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeConsumer.kt deleted file mode 100644 index 986be05ffb425c4993817464ef4cc01fdbff1193..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeConsumer.kt +++ /dev/null @@ -1,49 +0,0 @@ -package de.rki.coronawarnapp.util.list - -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.RecyclerView -import de.rki.coronawarnapp.util.lists.HasStableId -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.contract - -/** - * [RecyclerView] item data model should implement this contract to consume the swipe gestures - */ -interface SwipeConsumer { - /** - * On swipe callback - * @param position [Int] item position - * @param direction [Int] from [ItemTouchHelper] such as [ItemTouchHelper.RIGHT] - */ - fun onSwipe(position: Int, direction: Int) -} - -/** - * returns true if the item is as [SwipeConsumer] , false otherwise - * and helps with smart cast - */ - -@OptIn(ExperimentalContracts::class) -fun HasStableId?.isSwipeable(): Boolean { - contract { - returns(true) implies (this@isSwipeable is SwipeConsumer) - } - return this != null && this is SwipeConsumer -} - -/** - * Indicates whether [RecyclerView.ViewHolder]'s can be moved (Dragged, Swiped) or not - * by default movementFlags = ACTION_STATE_IDLE which indicates that the view does not move - * this behaviour can be overridden and provide any flag from [ItemTouchHelper] - */ -interface Movable { - val movementFlags: Int get() = ItemTouchHelper.ACTION_STATE_IDLE -} - -@OptIn(ExperimentalContracts::class) -fun RecyclerView.ViewHolder?.isMovable(): Boolean { - contract { - returns(true) implies (this@isMovable is Movable) - } - return this != null && this is Movable -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeExtension.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeExtension.kt index ed2b66642401ff3d7557d79c7a47b661e176e012..0201f5f6c70d29320e18b22ef31673779616442a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeExtension.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/SwipeExtension.kt @@ -18,20 +18,15 @@ import kotlin.math.min /** * On [RecyclerView] item swipe listener * @param context [Context] - * @param onSwipe on swipe callback. It passes item's position and swipe direction + * @param onSwipe if you want to override the swipe callback globally * - * Usage: - * ``` - * RecyclerView.onSwipeItem( - * context = requireContext() - * ) { position, direction -> - * // Do operation here - * } - * ``` + * After calling this on a recyclerview, every ViewHolder that implements [Swipeable] is swipeable. */ -fun RecyclerView.onSwipeItem( +fun RecyclerView.setupSwipe( context: Context, - onSwipe: (position: Int, direction: Int) -> Unit + onSwipe: (holder: RecyclerView.ViewHolder, direction: Int) -> Unit = { holder, direction -> + (holder as? Swipeable)?.let { holder.onSwipe(holder, direction) } + } ) { ItemTouchHelper( SwipeCallback( @@ -46,11 +41,10 @@ fun RecyclerView.onSwipeItem( */ private class SwipeCallback( context: Context, - private val action: (position: Int, direction: Int) -> Unit -) : ItemTouchHelper.SimpleCallback( - 0, - ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT -) { + private val action: (holder: RecyclerView.ViewHolder, direction: Int) -> Unit, + private val dragDirs: Int = 0, + private val swipeDirs: Int = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT, +) : ItemTouchHelper.SimpleCallback(dragDirs, swipeDirs) { private val icon = context.getDrawableCompat(R.drawable.ic_delete)!! private val iconMargin = context.resources.getDimensionPixelSize(R.dimen.swipe_icon_margin) private val radius = context.resources.getDimensionPixelSize(R.dimen.radius_card).toFloat() @@ -69,7 +63,7 @@ private class SwipeCallback( ): Boolean = false override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { - action(viewHolder.adapterPosition, direction) + action(viewHolder, direction) } override fun onChildDraw( @@ -102,9 +96,12 @@ private class SwipeCallback( } } - override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { - if (viewHolder.isMovable()) return viewHolder.movementFlags - return super.getMovementFlags(recyclerView, viewHolder) + override fun getMovementFlags( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder + ): Int = when (viewHolder) { + is Swipeable -> viewHolder.movementFlags ?: ItemTouchHelper.Callback.makeMovementFlags(dragDirs, swipeDirs) + else -> ItemTouchHelper.ACTION_STATE_IDLE } private fun onSwipeLeft( diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/Swipeable.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/Swipeable.kt new file mode 100644 index 0000000000000000000000000000000000000000..2b9e42c8bc780f40bc28719cc0740638519c8553 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/list/Swipeable.kt @@ -0,0 +1,23 @@ +package de.rki.coronawarnapp.util.list + +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView + +/** + * [RecyclerView] item data model should implement this contract to consume the swipe gestures + */ +interface Swipeable { + /** + * Indicates whether [RecyclerView.ViewHolder]'s can be moved (Dragged, Swiped) or not + * by default movementFlags = ACTION_STATE_IDLE which indicates that the view does not move + * this behaviour can be overridden and provide any flag from [ItemTouchHelper] + */ + val movementFlags: Int? get() = null + + /** + * On swipe callback + * @param holder [RecyclerView.ViewHolder] that was swiped + * @param direction [Int] from [ItemTouchHelper] such as [ItemTouchHelper.RIGHT] + */ + fun onSwipe(holder: RecyclerView.ViewHolder, direction: Int) +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListFragment.kt index c2809813063e64dd01f703b77609d1b7fd995c72..9c3768891b87a83378c714760d5f9f1949dc9b9f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/VaccinationListFragment.kt @@ -18,8 +18,7 @@ import de.rki.coronawarnapp.databinding.FragmentVaccinationListBinding import de.rki.coronawarnapp.ui.qrcode.fullscreen.QrCodeFullScreenFragmentArgs import de.rki.coronawarnapp.ui.view.onOffsetChange import de.rki.coronawarnapp.util.di.AutoInject -import de.rki.coronawarnapp.util.list.isSwipeable -import de.rki.coronawarnapp.util.list.onSwipeItem +import de.rki.coronawarnapp.util.list.setupSwipe import de.rki.coronawarnapp.util.lists.diffutil.update import de.rki.coronawarnapp.util.ui.doNavigate import de.rki.coronawarnapp.util.ui.popBackStack @@ -62,12 +61,7 @@ class VaccinationListFragment : Fragment(R.layout.fragment_vaccination_list), Au recyclerViewVaccinationList.apply { adapter = vaccinationListAdapter - onSwipeItem(requireContext()) { position, direction -> - val vaccinationItem = vaccinationListAdapter.data[position] - if (vaccinationItem.isSwipeable()) { - vaccinationItem.onSwipe(position, direction) - } - } + setupSwipe(requireContext()) } viewModel.uiState.observe(viewLifecycleOwner) { uiState -> @@ -160,10 +154,8 @@ class VaccinationListFragment : Fragment(R.layout.fragment_vaccination_list), Au setPositiveButton(R.string.vaccination_list_deletion_dialog_positive_button) { _, _ -> viewModel.deleteVaccination(vaccinationCertificateId) } - setNegativeButton(R.string.vaccination_list_deletion_dialog_negative_button) { _, _ -> - position?.let { vaccinationListAdapter.notifyItemChanged(it) } - } - setOnCancelListener { + setNegativeButton(R.string.vaccination_list_deletion_dialog_negative_button) { _, _ -> } + setOnDismissListener { position?.let { vaccinationListAdapter.notifyItemChanged(it) } } }.show() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListImmunityInformationCardItemVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListImmunityInformationCardItemVH.kt index d347b79da0bb987eec23e50db02be2c4a8d2e913..f6824b79b04a1ca22d84eb29a73a7871ff0bc2d0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListImmunityInformationCardItemVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListImmunityInformationCardItemVH.kt @@ -3,7 +3,6 @@ package de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder import android.view.ViewGroup import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.VaccinationListImmunityCardBinding -import de.rki.coronawarnapp.util.list.Movable import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListAdapter import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListItem import de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder.VaccinationListImmunityInformationCardItemVH.VaccinationListImmunityInformationCardItem @@ -13,8 +12,7 @@ class VaccinationListImmunityInformationCardItemVH(parent: ViewGroup) : VaccinationListAdapter.ItemVH<VaccinationListImmunityInformationCardItem, VaccinationListImmunityCardBinding>( layoutRes = R.layout.vaccination_list_immunity_card, parent = parent - ), - Movable { + ) { override val viewBinding: Lazy<VaccinationListImmunityCardBinding> = lazy { VaccinationListImmunityCardBinding.bind(itemView) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListNameCardItemVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListNameCardItemVH.kt index 392007562219dade65d905972494b9cbd9749a91..5cd1501ca2a27854aeedeb23575a690a5938ec3e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListNameCardItemVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListNameCardItemVH.kt @@ -3,7 +3,6 @@ package de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder import android.view.ViewGroup import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.VaccinationListNameCardBinding -import de.rki.coronawarnapp.util.list.Movable import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListAdapter import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListItem import de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder.VaccinationListNameCardItemVH.VaccinationListNameCardItem @@ -12,8 +11,7 @@ class VaccinationListNameCardItemVH(parent: ViewGroup) : VaccinationListAdapter.ItemVH<VaccinationListNameCardItem, VaccinationListNameCardBinding>( layoutRes = R.layout.vaccination_list_name_card, parent = parent - ), - Movable { + ) { override val viewBinding: Lazy<VaccinationListNameCardBinding> = lazy { VaccinationListNameCardBinding.bind(itemView) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListQrCodeCardItemVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListQrCodeCardItemVH.kt index 8a41db8da28eefb4a77a4974b2cadbdb4acd9372..f5741bd7abbf24b72d689b4c618a6359d67d462d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListQrCodeCardItemVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListQrCodeCardItemVH.kt @@ -5,7 +5,6 @@ import android.view.ViewGroup import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.VaccinationListQrcodeCardBinding import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortDayFormat -import de.rki.coronawarnapp.util.list.Movable import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListAdapter import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListItem import de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder.VaccinationListQrCodeCardItemVH.VaccinationListQrCodeCardItem @@ -16,8 +15,7 @@ class VaccinationListQrCodeCardItemVH(parent: ViewGroup) : VaccinationListAdapter.ItemVH<VaccinationListQrCodeCardItem, VaccinationListQrcodeCardBinding>( layoutRes = R.layout.vaccination_list_qrcode_card, parent = parent - ), - Movable { + ) { override val viewBinding: Lazy<VaccinationListQrcodeCardBinding> = lazy { VaccinationListQrcodeCardBinding.bind(itemView) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListVaccinationCardItemVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListVaccinationCardItemVH.kt index f38f54c83705e5400abdcd8c42edcea95867e4cd..82f2a8388585b70ba8f570710b5728f9f1f91889 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListVaccinationCardItemVH.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/vaccination/ui/list/adapter/viewholder/VaccinationListVaccinationCardItemVH.kt @@ -3,9 +3,10 @@ package de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder import android.view.Gravity import android.view.ViewGroup import androidx.appcompat.widget.PopupMenu +import androidx.recyclerview.widget.RecyclerView import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.VaccinationListVaccinationCardBinding -import de.rki.coronawarnapp.util.list.SwipeConsumer +import de.rki.coronawarnapp.util.list.Swipeable import de.rki.coronawarnapp.vaccination.core.VaccinatedPerson import de.rki.coronawarnapp.vaccination.core.VaccinatedPerson.Status.COMPLETE import de.rki.coronawarnapp.vaccination.core.VaccinatedPerson.Status.IMMUNITY @@ -15,13 +16,18 @@ import de.rki.coronawarnapp.vaccination.ui.list.adapter.VaccinationListItem import de.rki.coronawarnapp.vaccination.ui.list.adapter.viewholder.VaccinationListVaccinationCardItemVH.VaccinationListVaccinationCardItem import java.util.Objects -class VaccinationListVaccinationCardItemVH( - parent: ViewGroup, -) : +class VaccinationListVaccinationCardItemVH(parent: ViewGroup) : VaccinationListAdapter.ItemVH<VaccinationListVaccinationCardItem, VaccinationListVaccinationCardBinding>( layoutRes = R.layout.vaccination_list_vaccination_card, parent = parent - ) { + ), + Swipeable { + + private var latestItem: VaccinationListVaccinationCardItem? = null + + override fun onSwipe(holder: RecyclerView.ViewHolder, direction: Int) { + latestItem?.let { it.onSwipeToDelete(it.vaccinationCertificateId, holder.adapterPosition) } + } override val viewBinding: Lazy<VaccinationListVaccinationCardBinding> = lazy { VaccinationListVaccinationCardBinding.bind(itemView) @@ -30,6 +36,8 @@ class VaccinationListVaccinationCardItemVH( item: VaccinationListVaccinationCardItem, payloads: List<Any> ) -> Unit = { item, _ -> + latestItem = item + item.apply { root.setOnClickListener { onCardClick.invoke(vaccinationCertificateId) @@ -82,7 +90,7 @@ class VaccinationListVaccinationCardItemVH( val onCardClick: (String) -> Unit, val onDeleteClick: (String) -> Unit, val onSwipeToDelete: (String, Int) -> Unit - ) : VaccinationListItem, SwipeConsumer { + ) : VaccinationListItem { override val stableId: Long = Objects.hash( vaccinationCertificateId, @@ -93,8 +101,6 @@ class VaccinationListVaccinationCardItemVH( isFinalVaccination ).toLong() - override fun onSwipe(position: Int, direction: Int) = onSwipeToDelete(vaccinationCertificateId, position) - // Ignore onCardClick Listener in equals() to avoid re-drawing when only the click listener is updated override fun equals(other: Any?): Boolean { if (this === other) return true