From cf361334c40f201c2cea552ad0c6c1cd7a70cff6 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Tue, 8 Jun 2021 13:10:54 -0300 Subject: [PATCH] Fix jank and decrease animation duration in share contact selection recycler. --- .../securesms/sharing/ShareActivity.java | 5 ++++- .../securesms/sharing/ShareFlowConstants.kt | 21 +++++++++++++++++++ .../sharing/ShareSelectionMappingModel.java | 10 ++++----- .../securesms/sharing/ShareViewModel.java | 10 ++++----- .../ShareInterstitialActivity.java | 7 +++++++ .../ShareInterstitialMappingModel.java | 10 ++++----- .../ShareInterstitialViewModel.java | 16 +++++++------- .../layout/share_contact_selection_item.xml | 1 - app/src/main/res/values/strings.xml | 2 +- 9 files changed, 54 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/sharing/ShareFlowConstants.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java index b3cb0bc7ed..033b1bb599 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareActivity.java @@ -49,7 +49,6 @@ import org.thoughtcrime.securesms.components.SearchToolbar; import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode; import org.thoughtcrime.securesms.conversation.ConversationIntents; import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.mediasend.Media; import org.thoughtcrime.securesms.mediasend.MediaSendActivity; import org.thoughtcrime.securesms.recipients.Recipient; @@ -67,6 +66,7 @@ import org.whispersystems.libsignal.util.guava.Optional; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; @@ -254,6 +254,9 @@ public class ShareActivity extends PassphraseRequiredActivity RecyclerView contactsRecycler = findViewById(R.id.selected_list); contactsRecycler.setAdapter(adapter); + RecyclerView.ItemAnimator itemAnimator = Objects.requireNonNull(contactsRecycler.getItemAnimator()); + ShareFlowConstants.applySelectedContactsRecyclerAnimationSpeeds(itemAnimator); + getSupportFragmentManager().beginTransaction() .replace(R.id.contact_selection_list_fragment, contactsFragment) .commit(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareFlowConstants.kt b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareFlowConstants.kt new file mode 100644 index 0000000000..1096dc477f --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareFlowConstants.kt @@ -0,0 +1,21 @@ +package org.thoughtcrime.securesms.sharing + +import androidx.recyclerview.widget.RecyclerView + +internal object ShareFlowConstants { + + private const val ADD_DURATION = 60L + private const val REMOVE_DURATION = 60L + private const val MOVE_DURATION = 125L + private const val CHANGE_DURATION = 125L + + @JvmStatic + fun applySelectedContactsRecyclerAnimationSpeeds( + itemAnimator: RecyclerView.ItemAnimator + ) { + itemAnimator.addDuration = ADD_DURATION + itemAnimator.removeDuration = REMOVE_DURATION + itemAnimator.moveDuration = MOVE_DURATION + itemAnimator.changeDuration = CHANGE_DURATION + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareSelectionMappingModel.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareSelectionMappingModel.java index f0033cbbd1..d21a033917 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareSelectionMappingModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/ShareSelectionMappingModel.java @@ -11,11 +11,11 @@ import org.thoughtcrime.securesms.util.MappingModel; class ShareSelectionMappingModel implements MappingModel { private final ShareContact shareContact; - private final boolean isLast; + private final boolean isFirst; - ShareSelectionMappingModel(@NonNull ShareContact shareContact, boolean isLast) { + ShareSelectionMappingModel(@NonNull ShareContact shareContact, boolean isFirst) { this.shareContact = shareContact; - this.isLast = isLast; + this.isFirst = isFirst; } @NonNull String getName(@NonNull Context context) { @@ -25,7 +25,7 @@ class ShareSelectionMappingModel implements MappingModel>> getSelectedContactModels() { + @NonNull LiveData getSelectedContactModels() { return Transformations.map(selectedContacts, set -> Stream.of(set) - .>mapIndexed((i, c) -> new ShareSelectionMappingModel(c, i == set.size() - 1)) - .toList()); + .mapIndexed((i, c) -> new ShareSelectionMappingModel(c, i == 0)) + .collect(MappingModelList.toMappingModelList())); } @NonNull LiveData getSmsShareRestriction() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java index 5b0c9bb42c..e80cee0d81 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialActivity.java @@ -8,6 +8,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.RecyclerView; import com.annimon.stream.Stream; @@ -23,11 +24,14 @@ import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.sharing.MultiShareArgs; import org.thoughtcrime.securesms.sharing.MultiShareDialogs; +import org.thoughtcrime.securesms.sharing.ShareFlowConstants; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.text.AfterTextChanged; +import java.util.Objects; + /** * Handles display and editing of a text message (with possible link preview) before it is forwarded * to multiple users. @@ -126,6 +130,9 @@ public class ShareInterstitialActivity extends PassphraseRequiredActivity { contactsRecycler = findViewById(R.id.selected_list); contactsRecycler.setAdapter(adapter); + RecyclerView.ItemAnimator itemAnimator = Objects.requireNonNull(contactsRecycler.getItemAnimator()); + ShareFlowConstants.applySelectedContactsRecyclerAnimationSpeeds(itemAnimator); + confirm.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { int pad = Math.abs(v.getWidth() + ViewUtil.dpToPx(16)); ViewUtil.setPaddingEnd(contactsRecycler, pad); diff --git a/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialMappingModel.java b/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialMappingModel.java index 27e35ac59c..c08bdc2cb8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialMappingModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/sharing/interstitial/ShareInterstitialMappingModel.java @@ -11,11 +11,11 @@ import org.thoughtcrime.securesms.util.viewholders.RecipientMappingModel; class ShareInterstitialMappingModel extends RecipientMappingModel { private final Recipient recipient; - private final boolean isLast; + private final boolean isFirst; - ShareInterstitialMappingModel(@NonNull Recipient recipient, boolean isLast) { + ShareInterstitialMappingModel(@NonNull Recipient recipient, boolean isFirst) { this.recipient = recipient; - this.isLast = isLast; + this.isFirst = isFirst; } @Override @@ -23,7 +23,7 @@ class ShareInterstitialMappingModel extends RecipientMappingModel>> recipients; - private final MutableLiveData draftText; +private final MultiShareArgs args; + private final MutableLiveData recipients; + private final MutableLiveData draftText; private LinkPreview linkPreview; @@ -37,12 +35,12 @@ private final MultiShareArgs args; repository.loadRecipients(args.getShareContactAndThreads(), list -> recipients.postValue(Stream.of(list) - .>mapIndexed((i, r) -> new ShareInterstitialMappingModel(r, i == list.size() - 1)) - .toList())); + .mapIndexed((i, r) -> new ShareInterstitialMappingModel(r, i == 0)) + .collect(MappingModelList.toMappingModelList()))); } - LiveData>> getRecipients() { + LiveData getRecipients() { return recipients; } diff --git a/app/src/main/res/layout/share_contact_selection_item.xml b/app/src/main/res/layout/share_contact_selection_item.xml index 76d428c4b5..a4770baf7d 100644 --- a/app/src/main/res/layout/share_contact_selection_item.xml +++ b/app/src/main/res/layout/share_contact_selection_item.xml @@ -6,5 +6,4 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" - android:paddingEnd="5sp" tools:text="@tools:sample/first_names" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a013ba9054..554a440451 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3251,7 +3251,7 @@ Share Send - %1$s, + , %1$s Sharing to multiple chats is only supported for Signal messages