diff --git a/app/src/main/java/org/thoughtcrime/securesms/GroupMembersDialog.java b/app/src/main/java/org/thoughtcrime/securesms/GroupMembersDialog.java index 0d11e111d8..10ce21803a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/GroupMembersDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/GroupMembersDialog.java @@ -35,6 +35,7 @@ public final class GroupMembersDialog { .show(); GroupMemberListView memberListView = dialog.findViewById(R.id.list_members); + memberListView.initializeAdapter(fragmentActivity); LiveGroup liveGroup = new LiveGroup(groupRecipient.requireGroupId()); LiveData> fullMembers = liveGroup.getFullMembers(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/Boost.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/Boost.kt index 1f86adecdc..900e223f73 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/Boost.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/subscription/boost/Boost.kt @@ -12,9 +12,6 @@ import androidx.annotation.VisibleForTesting import androidx.appcompat.widget.AppCompatEditText import androidx.core.animation.doOnEnd import androidx.core.text.isDigitsOnly -import androidx.core.widget.addTextChangedListener -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner import com.google.android.material.button.MaterialButton import org.signal.core.util.money.FiatMoney import org.thoughtcrime.securesms.R @@ -56,7 +53,7 @@ data class Boost( override fun areItemsTheSame(newItem: LoadingModel): Boolean = true } - class LoadingViewHolder(itemView: View) : MappingViewHolder(itemView), DefaultLifecycleObserver { + class LoadingViewHolder(itemView: View) : MappingViewHolder(itemView) { private val animator: Animator = AnimatorSet().apply { val fadeTo25Animator = ObjectAnimator.ofFloat(itemView, "alpha", 0.8f, 0.25f).apply { @@ -68,17 +65,17 @@ data class Boost( } playSequentially(fadeTo25Animator, fadeTo80Animator) - doOnEnd { start() } - } - - init { - lifecycle.addObserver(this) + doOnEnd { + if (itemView.isAttachedToWindow) { + start() + } + } } override fun bind(model: LoadingModel) { } - override fun onResume(owner: LifecycleOwner) { + override fun onAttachedToWindow() { if (animator.isStarted) { animator.resume() } else { @@ -86,7 +83,7 @@ data class Boost( } } - override fun onDestroy(owner: LifecycleOwner) { + override fun onDetachedFromWindow() { animator.pause() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt index 530574e23c..7e418389d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt @@ -732,7 +732,7 @@ class ConversationSettingsFragment : DSLSettingsFragment( } private fun showGroupInvitesSentDialog(showGroupInvitesSentDialog: ConversationSettingsEvent.ShowGroupInvitesSentDialog) { - GroupInviteSentDialog.showInvitesSent(requireContext(), showGroupInvitesSentDialog.invitesSentTo) + GroupInviteSentDialog.showInvitesSent(requireContext(), viewLifecycleOwner, showGroupInvitesSentDialog.invitesSentTo) } private fun showMembersAdded(showMembersAdded: ConversationSettingsEvent.ShowMembersAdded) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java index 5aeb44393f..f1b464a34b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ShowAdminsBottomSheetDialog.java @@ -68,6 +68,7 @@ public final class ShowAdminsBottomSheetDialog extends BottomSheetDialogFragment disposables.bindTo(getViewLifecycleOwner().getLifecycle()); GroupMemberListView list = view.findViewById(R.id.show_admin_list); + list.initializeAdapter(getViewLifecycleOwner()); list.setDisplayOnlyMembers(Collections.emptyList()); list.setRecipientClickListener(recipient -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListAdapter.java index 59103381c0..4538708cd9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/GroupMemberListAdapter.java @@ -10,6 +10,8 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.Observer; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; @@ -18,9 +20,6 @@ import org.thoughtcrime.securesms.badges.BadgeImageView; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.emoji.EmojiTextView; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.FeatureFlags; -import org.thoughtcrime.securesms.util.LifecycleRecyclerAdapter; -import org.thoughtcrime.securesms.util.LifecycleViewHolder; import org.thoughtcrime.securesms.util.Util; import java.util.ArrayList; @@ -28,7 +27,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -final class GroupMemberListAdapter extends LifecycleRecyclerAdapter { +final class GroupMemberListAdapter extends RecyclerView.Adapter { private static final int FULL_MEMBER = 0; private static final int OWN_INVITE_PENDING = 1; @@ -41,14 +40,16 @@ final class GroupMemberListAdapter extends LifecycleRecyclerAdapter recipients) { @@ -78,6 +79,12 @@ final class GroupMemberListAdapter extends LifecycleRecyclerAdapter busyObserver; + + Runnable startListeningToBusyChanges; + Runnable stopListeningToBusyChanges; ViewHolder(@NonNull View itemView, @Nullable RecipientClickListener recipientClickListener, @Nullable RecipientLongClickListener recipientLongClickListener, @Nullable AdminActionsListener adminActionsListener, @NonNull SelectionChangeListener selectionChangeListener, - boolean selectable) + boolean selectable, + @NonNull LifecycleOwner lifecycleOwner) { super(itemView); @@ -212,6 +230,19 @@ final class GroupMemberListAdapter extends LifecycleRecyclerAdapter { - busyProgress.setVisibility(busy ? View.VISIBLE : View.GONE); - popupMenu.setVisibility(busy ? View.GONE : View.VISIBLE); - }); + memberEntry.getBusy().observe(lifecycleOwner, busyObserver); + stopListeningToBusyChanges = () -> memberEntry.getBusy().removeObserver(busyObserver); selected.setChecked(isSelected); if (!selectable && !isSelected) { @@ -299,9 +328,10 @@ final class GroupMemberListAdapter extends LifecycleRecyclerAdapter viewModel.setSelection(Stream.of(selection) .select(GroupMemberEntry.FullMember.class) .collect(Collectors.toSet()))); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsActivity.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsActivity.java index 85ac7b4ef6..dd42c97930 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsActivity.java @@ -66,7 +66,7 @@ public class AddGroupDetailsActivity extends PassphraseRequiredActivity implemen long threadId, @NonNull List invitedMembers) { - Dialog dialog = GroupInviteSentDialog.showInvitesSent(this, invitedMembers); + Dialog dialog = GroupInviteSentDialog.showInvitesSent(this, this, invitedMembers); if (dialog != null) { dialog.setOnDismissListener((d) -> goToConversation(recipientId, threadId)); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java index c03b23c582..d37ba0b454 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java @@ -104,6 +104,7 @@ public class AddGroupDetailsFragment extends LoggingFragment { View addLater = view.findViewById(R.id.add_later); TextView disappearingMessageValue = view.findViewById(R.id.group_disappearing_messages_value); + members.initializeAdapter(getViewLifecycleOwner()); avatarPlaceholder = VectorDrawableCompat.create(getResources(), R.drawable.ic_camera_outline_32_ultramarine, requireActivity().getTheme()); if (savedInstanceState == null) { @@ -133,7 +134,7 @@ public class AddGroupDetailsFragment extends LoggingFragment { gv2Warning.setVisibility(nonGv2CapableMembers.isEmpty() ? View.GONE : View.VISIBLE); gv2Warning.setText(requireContext().getResources().getQuantityString(R.plurals.AddGroupDetailsFragment__d_members_do_not_support_new_groups_so_this_group_cannot_be_created, nonGv2CapableMembers.size(), nonGv2CapableMembers.size())); gv2Warning.setLearnMoreVisible(true); - gv2Warning.setOnLinkClickListener(v -> NonGv2MemberDialog.showNonGv2Members(requireContext(), nonGv2CapableMembers)); + gv2Warning.setOnLinkClickListener(v -> NonGv2MemberDialog.showNonGv2Members(requireContext(), getViewLifecycleOwner(), nonGv2CapableMembers)); }); viewModel.getAvatar().observe(getViewLifecycleOwner(), avatarBytes -> { if (avatarBytes == null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/dialogs/NonGv2MemberDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/dialogs/NonGv2MemberDialog.java index 87858e5c70..8cf0e8a9c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/dialogs/NonGv2MemberDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/dialogs/NonGv2MemberDialog.java @@ -6,6 +6,7 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import androidx.lifecycle.LifecycleOwner; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; @@ -20,7 +21,7 @@ public final class NonGv2MemberDialog { private NonGv2MemberDialog() { } - public static @Nullable Dialog showNonGv2Members(@NonNull Context context, @NonNull List recipients) { + public static @Nullable Dialog showNonGv2Members(@NonNull Context context, @NonNull LifecycleOwner lifecycleOwner, @NonNull List recipients) { int size = recipients.size(); if (size == 0) { return null; @@ -42,6 +43,8 @@ public final class NonGv2MemberDialog { if (size > 1) { GroupMemberListView nonGv2CapableMembers = dialog.findViewById(R.id.list_non_gv2_members); + nonGv2CapableMembers.initializeAdapter(lifecycleOwner); + List pendingMembers = new ArrayList<>(recipients.size()); for (Recipient r : recipients) { pendingMembers.add(new GroupMemberEntry.NewGroupCandidate(r)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesFragment.java index ee38bfed8a..7229f3e060 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/invited/PendingMemberInvitesFragment.java @@ -49,6 +49,9 @@ public class PendingMemberInvitesFragment extends Fragment { youInvitedEmptyState = view.findViewById(R.id.no_pending_from_you); othersInvitedEmptyState = view.findViewById(R.id.no_pending_from_others); + youInvited.initializeAdapter(getViewLifecycleOwner()); + othersInvited.initializeAdapter(getViewLifecycleOwner()); + youInvited.setRecipientClickListener(recipient -> RecipientBottomSheetDialogFragment.create(recipient.getId(), null) .show(requireActivity().getSupportFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/requesting/RequestingMembersFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/requesting/RequestingMembersFragment.java index 04c2ab229d..b99fb1ecf6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/requesting/RequestingMembersFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/requesting/RequestingMembersFragment.java @@ -51,6 +51,8 @@ public class RequestingMembersFragment extends Fragment { noRequestingMessage = view.findViewById(R.id.no_requesting); requestingExplanation = view.findViewById(R.id.requesting_members_explain); + requestingMembers.initializeAdapter(getViewLifecycleOwner()); + requestingMembers.setRecipientClickListener(recipient -> RecipientBottomSheetDialogFragment.create(recipient.getId(), null) .show(requireActivity().getSupportFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/dialogs/GroupInviteSentDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/dialogs/GroupInviteSentDialog.java index b118f079ad..0fbe188cf2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/dialogs/GroupInviteSentDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/managegroup/dialogs/GroupInviteSentDialog.java @@ -6,6 +6,7 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import androidx.lifecycle.LifecycleOwner; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; @@ -20,7 +21,7 @@ public final class GroupInviteSentDialog { private GroupInviteSentDialog() { } - public static @Nullable Dialog showInvitesSent(@NonNull Context context, @NonNull List recipients) { + public static @Nullable Dialog showInvitesSent(@NonNull Context context, @NonNull LifecycleOwner lifecycleOwner, @NonNull List recipients) { int size = recipients.size(); if (size == 0) { return null; @@ -43,6 +44,8 @@ public final class GroupInviteSentDialog { if (size > 1) { GroupMemberListView invitees = dialog.findViewById(R.id.list_invitees); + invitees.initializeAdapter(lifecycleOwner); + List pendingMembers = new ArrayList<>(recipients.size()); for (Recipient r : recipients) { pendingMembers.add(new GroupMemberEntry.PendingMember(r)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInfoBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInfoBottomSheetDialogFragment.java index 08097b937f..40fe437b50 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInfoBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInfoBottomSheetDialogFragment.java @@ -72,6 +72,9 @@ public final class GroupsV1MigrationInfoBottomSheetDialogFragment extends Bottom this.droppedTitle = view.findViewById(R.id.gv1_learn_more_dropped_title); this.droppedList = view.findViewById(R.id.gv1_learn_more_dropped_list); + pendingList.initializeAdapter(getViewLifecycleOwner()); + droppedList.initializeAdapter(getViewLifecycleOwner()); + //noinspection ConstantConditions GroupMigrationMembershipChange membershipChange = GroupMigrationMembershipChange.deserialize(getArguments().getString(KEY_MEMBERSHIP_CHANGE)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInitiationBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInitiationBottomSheetDialogFragment.java index 7e0447ccc9..ac148f1a00 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInitiationBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationInitiationBottomSheetDialogFragment.java @@ -77,6 +77,9 @@ public final class GroupsV1MigrationInitiationBottomSheetDialogFragment extends this.upgradeButton = view.findViewById(R.id.gv1_migrate_upgrade_button); this.spinner = view.findViewById(R.id.gv1_migrate_spinner); + inviteList.initializeAdapter(getViewLifecycleOwner()); + ineligibleList.initializeAdapter(getViewLifecycleOwner()); + inviteList.setNestedScrollingEnabled(false); ineligibleList.setNestedScrollingEnabled(false); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java index 2e99de1abf..4d00253f6a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java @@ -65,6 +65,7 @@ public final class GroupsV1MigrationSuggestionsDialog { .show(); GroupMemberListView memberListView = dialog.findViewById(R.id.list_members); + memberListView.initializeAdapter(fragmentActivity); SimpleTask.run(() -> Recipient.resolvedList(suggestions), memberListView::setDisplayOnlyMembers); diff --git a/app/src/main/java/org/thoughtcrime/securesms/subscription/Subscription.kt b/app/src/main/java/org/thoughtcrime/securesms/subscription/Subscription.kt index 579bf15ca1..1f1d919491 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/subscription/Subscription.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/subscription/Subscription.kt @@ -8,7 +8,6 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.animation.doOnEnd import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner import org.signal.core.util.money.FiatMoney import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.badges.BadgeImageView @@ -56,17 +55,17 @@ data class Subscription( } playSequentially(fadeTo25Animator, fadeTo80Animator) - doOnEnd { start() } - } - - init { - lifecycle.addObserver(this) + doOnEnd { + if (itemView.isAttachedToWindow) { + start() + } + } } override fun bind(model: LoaderModel) { } - override fun onResume(owner: LifecycleOwner) { + override fun onAttachedToWindow() { if (animator.isStarted) { animator.resume() } else { @@ -74,7 +73,7 @@ data class Subscription( } } - override fun onDestroy(owner: LifecycleOwner) { + override fun onDetachedFromWindow() { animator.pause() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/LifecycleRecyclerAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/util/LifecycleRecyclerAdapter.java deleted file mode 100644 index 04150f96d3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/util/LifecycleRecyclerAdapter.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.thoughtcrime.securesms.util; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -public abstract class LifecycleRecyclerAdapter extends RecyclerView.Adapter { - - @Override - public void onViewAttachedToWindow(@NonNull VH holder) { - super.onViewAttachedToWindow(holder); - holder.onAttachedToWindow(); - } - - @Override - public void onViewDetachedFromWindow(@NonNull VH holder) { - super.onViewDetachedFromWindow(holder); - holder.onDetachedFromWindow(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/LifecycleViewHolder.java b/app/src/main/java/org/thoughtcrime/securesms/util/LifecycleViewHolder.java deleted file mode 100644 index aa59015aaa..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/util/LifecycleViewHolder.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.thoughtcrime.securesms.util; - -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.LifecycleRegistry; -import androidx.recyclerview.widget.RecyclerView; - -public abstract class LifecycleViewHolder extends RecyclerView.ViewHolder implements LifecycleOwner { - - private final LifecycleRegistry lifecycleRegistry; - - public LifecycleViewHolder(@NonNull View itemView) { - super(itemView); - - lifecycleRegistry = new LifecycleRegistry(this); - } - - void onAttachedToWindow() { - lifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED); - } - - void onDetachedFromWindow() { - lifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED); - } - - @Override - public @NonNull Lifecycle getLifecycle() { - return lifecycleRegistry; - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/MappingViewHolder.java b/app/src/main/java/org/thoughtcrime/securesms/util/MappingViewHolder.java index 75d5dcbfe6..1ba829dfac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/MappingViewHolder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/MappingViewHolder.java @@ -5,12 +5,12 @@ import android.view.View; import androidx.annotation.IdRes; import androidx.annotation.NonNull; -import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; import java.util.LinkedList; import java.util.List; -public abstract class MappingViewHolder extends LifecycleViewHolder implements LifecycleOwner { +public abstract class MappingViewHolder extends RecyclerView.ViewHolder { protected final Context context; protected final List payload; @@ -29,6 +29,12 @@ public abstract class MappingViewHolder extends LifecycleViewHolder imple return itemView.getContext(); } + public void onAttachedToWindow() { + } + + public void onDetachedFromWindow() { + } + public abstract void bind(@NonNull Model model); public void setPayload(@NonNull List payload) {