Clean up and speed up conversation list item view.

fork-5.53.8
Greyson Parrelli 2020-12-20 17:40:54 -05:00 zatwierdzone przez Alan Evans
rodzic cdd7b2deb9
commit aa3eb78956
6 zmienionych plików z 172 dodań i 223 usunięć

Wyświetl plik

@ -12,6 +12,7 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter; import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.signal.core.util.logging.Log;
import org.signal.paging.PagingController; import org.signal.paging.PagingController;
import org.thoughtcrime.securesms.BindableConversationListItem; import org.thoughtcrime.securesms.BindableConversationListItem;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;

Wyświetl plik

@ -40,7 +40,11 @@ abstract class ConversationListDataSource implements PagedDataSource<Conversatio
@Override @Override
public int size() { public int size() {
return getTotalCount(); long startTime = System.currentTimeMillis();
int count = getTotalCount();
Log.d(TAG, "[size(), " + getClass().getSimpleName() + "] " + (System.currentTimeMillis() - startTime) + " ms");
return count;
} }
@Override @Override

Wyświetl plik

@ -20,18 +20,18 @@ import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.RippleDrawable; import android.graphics.drawable.RippleDrawable;
import android.os.Build.VERSION; import android.os.Build;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
@ -64,7 +64,6 @@ import org.thoughtcrime.securesms.util.Debouncer;
import org.thoughtcrime.securesms.util.ExpirationUtil; import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.SearchUtil; import org.thoughtcrime.securesms.util.SearchUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil; import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import java.util.Collections; import java.util.Collections;
@ -73,7 +72,7 @@ import java.util.Set;
import static org.thoughtcrime.securesms.database.model.LiveUpdateMessage.recipientToStringAsync; import static org.thoughtcrime.securesms.database.model.LiveUpdateMessage.recipientToStringAsync;
public final class ConversationListItem extends RelativeLayout public final class ConversationListItem extends ConstraintLayout
implements RecipientForeverObserver, implements RecipientForeverObserver,
BindableConversationListItem, BindableConversationListItem,
Unbindable, Unbindable,
@ -90,7 +89,6 @@ public final class ConversationListItem extends RelativeLayout
private LiveRecipient recipient; private LiveRecipient recipient;
private long threadId; private long threadId;
private GlideRequests glideRequests; private GlideRequests glideRequests;
private View subjectContainer;
private TextView subjectView; private TextView subjectView;
private TypingIndicatorView typingView; private TypingIndicatorView typingView;
private FromTextView fromView; private FromTextView fromView;
@ -122,21 +120,17 @@ public final class ConversationListItem extends RelativeLayout
@Override @Override
protected void onFinishInflate() { protected void onFinishInflate() {
super.onFinishInflate(); super.onFinishInflate();
this.subjectContainer = findViewById(R.id.subject_container); this.subjectView = findViewById(R.id.conversation_list_item_summary);
this.subjectView = findViewById(R.id.subject); this.typingView = findViewById(R.id.conversation_list_item_typing_indicator);
this.typingView = findViewById(R.id.typing_indicator); this.fromView = findViewById(R.id.conversation_list_item_name);
this.fromView = findViewById(R.id.from); this.dateView = findViewById(R.id.conversation_list_item_date);
this.dateView = findViewById(R.id.date); this.deliveryStatusIndicator = findViewById(R.id.conversation_list_item_status);
this.deliveryStatusIndicator = findViewById(R.id.delivery_status); this.alertView = findViewById(R.id.conversation_list_item_alert);
this.alertView = findViewById(R.id.indicators_parent); this.contactPhotoImage = findViewById(R.id.conversation_list_item_avatar);
this.contactPhotoImage = findViewById(R.id.contact_photo_image); this.thumbnailView = findViewById(R.id.conversation_list_item_thumbnail);
this.thumbnailView = findViewById(R.id.thumbnail); this.archivedView = findViewById(R.id.conversation_list_item_archived);
this.archivedView = findViewById(R.id.archived); this.unreadIndicator = findViewById(R.id.conversation_list_item_unread_indicator);
this.unreadIndicator = findViewById(R.id.unread_indicator);
thumbnailView.setClickable(false); thumbnailView.setClickable(false);
ViewUtil.setTextViewGravityStart(this.fromView, getContext());
ViewUtil.setTextViewGravityStart(this.subjectView, getContext());
} }
@Override @Override
@ -349,19 +343,8 @@ public final class ConversationListItem extends RelativeLayout
if (thread.getSnippetUri() != null) { if (thread.getSnippetUri() != null) {
this.thumbnailView.setVisibility(View.VISIBLE); this.thumbnailView.setVisibility(View.VISIBLE);
this.thumbnailView.setImageResource(glideRequests, thread.getSnippetUri()); this.thumbnailView.setImageResource(glideRequests, thread.getSnippetUri());
LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectContainer .getLayoutParams();
subjectParams.addRule(RelativeLayout.LEFT_OF, R.id.thumbnail);
subjectParams.addRule(RelativeLayout.START_OF, R.id.thumbnail);
this.subjectContainer.setLayoutParams(subjectParams);
this.post(new ThumbnailPositioner(thumbnailView, archivedView, deliveryStatusIndicator, dateView));
} else { } else {
this.thumbnailView.setVisibility(View.GONE); this.thumbnailView.setVisibility(View.GONE);
LayoutParams subjectParams = (RelativeLayout.LayoutParams)this.subjectContainer.getLayoutParams();
subjectParams.addRule(RelativeLayout.LEFT_OF, R.id.status);
subjectParams.addRule(RelativeLayout.START_OF, R.id.status);
this.subjectContainer.setLayoutParams(subjectParams);
} }
} }
@ -403,7 +386,7 @@ public final class ConversationListItem extends RelativeLayout
} }
private void setRippleColor(Recipient recipient) { private void setRippleColor(Recipient recipient) {
if (VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
((RippleDrawable)(getBackground()).mutate()) ((RippleDrawable)(getBackground()).mutate())
.setColor(ColorStateList.valueOf(recipient.getColor().toConversationColor(getContext()))); .setColor(ColorStateList.valueOf(recipient.getColor().toConversationColor(getContext())));
} }
@ -549,37 +532,4 @@ public final class ConversationListItem extends RelativeLayout
updateTypingIndicator(typingThreads); updateTypingIndicator(typingThreads);
} }
} }
private static class ThumbnailPositioner implements Runnable {
private final View thumbnailView;
private final View archivedView;
private final View deliveryStatusView;
private final View dateView;
ThumbnailPositioner(View thumbnailView, View archivedView, View deliveryStatusView, View dateView) {
this.thumbnailView = thumbnailView;
this.archivedView = archivedView;
this.deliveryStatusView = deliveryStatusView;
this.dateView = dateView;
}
@Override
public void run() {
LayoutParams thumbnailParams = (RelativeLayout.LayoutParams)thumbnailView.getLayoutParams();
if (archivedView.getVisibility() == View.VISIBLE &&
(archivedView.getWidth() + deliveryStatusView.getWidth()) > dateView.getWidth())
{
thumbnailParams.addRule(RelativeLayout.LEFT_OF, R.id.status);
thumbnailParams.addRule(RelativeLayout.START_OF, R.id.status);
} else {
thumbnailParams.addRule(RelativeLayout.LEFT_OF, R.id.date);
thumbnailParams.addRule(RelativeLayout.START_OF, R.id.date);
}
thumbnailView.setLayoutParams(thumbnailParams);
}
}
} }

Wyświetl plik

@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
@ -17,7 +18,7 @@ import org.thoughtcrime.securesms.mms.GlideRequests;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
public class ConversationListItemAction extends LinearLayout implements BindableConversationListItem { public class ConversationListItemAction extends FrameLayout implements BindableConversationListItem {
private TextView description; private TextView description;

Wyświetl plik

@ -2,7 +2,6 @@
<org.thoughtcrime.securesms.conversationlist.ConversationListItemAction <org.thoughtcrime.securesms.conversationlist.ConversationListItemAction
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="70dp"> android:layout_height="70dp">

Wyświetl plik

@ -3,171 +3,165 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/conversation_list_item_background"
android:layout_width="match_parent" android:layout_width="match_parent"
android:focusable="true"
android:nextFocusRight="@+id/fab"
android:nextFocusLeft="@+id/container"
android:layout_height="72dp" android:layout_height="72dp"
android:background="@drawable/conversation_list_item_background"
android:focusable="true"
android:nextFocusLeft="@+id/container"
android:nextFocusRight="@+id/fab"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp"> android:paddingEnd="16dp">
<FrameLayout
android:id="@+id/avatar_container"
android:layout_width="58dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="2dp">
<org.thoughtcrime.securesms.components.AvatarImageView <org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/contact_photo_image" android:id="@+id/conversation_list_item_avatar"
android:foreground="@drawable/contact_photo_background"
android:layout_width="52dp" android:layout_width="52dp"
android:layout_height="52dp" android:layout_height="52dp"
tools:src="@drawable/ic_contact_picture" android:contentDescription="@string/conversation_list_item_view__contact_photo_image"
android:contentDescription="@string/conversation_list_item_view__contact_photo_image" /> android:foreground="@drawable/contact_photo_background"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:src="@drawable/ic_contact_picture" />
<TextView <TextView
android:id="@+id/unread_indicator" android:id="@+id/conversation_list_item_unread_indicator"
style="@style/Signal.Text.Caption"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end|top" android:background="@drawable/unread_count_background"
style="@style/Signal.Text.Caption"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:gravity="center"
android:minWidth="@dimen/unread_count_bubble_diameter" android:minWidth="@dimen/unread_count_bubble_diameter"
android:padding="5sp" android:padding="5sp"
android:background="@drawable/unread_count_background"
android:textColor="@color/core_white" android:textColor="@color/core_white"
android:gravity="center" app:layout_constraintEnd_toEndOf="@id/conversation_list_item_avatar"
app:layout_constraintTop_toTopOf="@id/conversation_list_item_avatar"
tools:text="1" /> tools:text="1" />
</FrameLayout>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/avatar_container"
android:weightSum="1"
android:orientation="horizontal">
<org.thoughtcrime.securesms.components.FromTextView <org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/from" android:id="@+id/conversation_list_item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/thumbnail"
style="@style/Signal.Text.Body" style="@style/Signal.Text.Body"
android:fontFamily="sans-serif-medium" android:layout_width="0dp"
android:textColor="@color/signal_text_primary" android:layout_height="wrap_content"
android:maxLines="1"
tools:text="Jules Bonnot"
android:ellipsize="end"
android:layout_marginBottom="2dp" android:layout_marginBottom="2dp"
android:drawablePadding="5dp"/> android:layout_marginStart="8dp"
android:drawablePadding="5dp"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:textColor="@color/signal_text_primary"
app:layout_constraintStart_toEndOf="@id/conversation_list_item_avatar"
app:layout_constraintEnd_toStartOf="@id/conversation_list_item_thumbnail"
app:layout_constraintTop_toTopOf="@id/conversation_list_item_avatar"
app:layout_constraintBottom_toTopOf="@id/conversation_list_item_summary"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Peter Parker" />
<org.thoughtcrime.securesms.components.AlertView <org.thoughtcrime.securesms.components.AlertView
android:id="@+id/indicators_parent" android:id="@+id/conversation_list_item_alert"
android:layout_width="18dp" android:layout_width="18dp"
android:layout_height="18dp" android:layout_height="18dp"
android:paddingTop="2dp"
android:layout_marginEnd="2dp" android:layout_marginEnd="2dp"
android:layout_alignParentStart="true" android:paddingTop="2dp"
android:layout_below="@id/from"
app:useSmallIcon="true"
android:visibility="gone" android:visibility="gone"
app:useSmallIcon="true"
app:layout_constraintTop_toTopOf="@id/conversation_list_item_summary"
app:layout_constraintBottom_toBottomOf="@id/conversation_list_item_summary"
app:layout_constraintStart_toStartOf="@id/conversation_list_item_name"
tools:visibility="visible" /> tools:visibility="visible" />
<FrameLayout
android:id="@+id/subject_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="1dp"
android:layout_below="@id/from"
android:layout_toEndOf="@id/indicators_parent"
android:layout_toStartOf="@+id/status">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView <org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/subject" android:id="@+id/conversation_list_item_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Signal.Text.Preview" style="@style/Signal.Text.Preview"
android:textColor="@color/signal_text_secondary" android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
tools:text="Wheels arrive at 3pm flat. This is a somewhat longer message." android:textColor="@color/signal_text_secondary"
android:ellipsize="end" /> tools:text="I'll send those photos over to the Bugle ASAP."
app:layout_constraintTop_toBottomOf="@id/conversation_list_item_name"
app:layout_constraintBottom_toBottomOf="@id/conversation_list_item_avatar"
app:layout_constraintStart_toEndOf="@id/conversation_list_item_alert"
app:layout_constraintEnd_toStartOf="@id/conversation_list_item_status_barrier"/>
<org.thoughtcrime.securesms.components.TypingIndicatorView <org.thoughtcrime.securesms.components.TypingIndicatorView
android:id="@+id/typing_indicator" android:id="@+id/conversation_list_item_typing_indicator"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:visibility="gone" android:visibility="gone"
app:typingIndicator_tint="@color/signal_icon_tint_secondary"/> tools:visibility="visible"
app:typingIndicator_tint="@color/signal_icon_tint_secondary"
</FrameLayout> app:layout_constraintStart_toStartOf="@id/conversation_list_item_summary"
app:layout_constraintTop_toTopOf="@id/conversation_list_item_summary"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.ThumbnailView
android:id="@+id/thumbnail" android:id="@+id/conversation_list_item_thumbnail"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:layout_toStartOf="@+id/date"
android:layout_alignParentTop="true"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_toStartOf="@+id/conversation_list_item_date"
android:contentDescription="@string/conversation_activity__attachment_thumbnail" android:contentDescription="@string/conversation_activity__attachment_thumbnail"
android:visibility="gone" android:visibility="gone"
tools:src="@drawable/ic_video_light" tools:visibility="visible"
tools:visibility="visible" /> app:layout_constraintTop_toTopOf="@id/conversation_list_item_avatar"
app:layout_constraintBottom_toBottomOf="@id/conversation_list_item_avatar"
app:layout_constraintEnd_toStartOf="@id/conversation_list_item_metadata_barrier"/>
<TextView android:id="@id/date" <TextView
android:layout_marginStart="3dp" android:id="@id/conversation_list_item_date"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignBaseline="@+id/from"
style="@style/Signal.Text.Caption" style="@style/Signal.Text.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="@color/signal_icon_tint_secondary" android:textColor="@color/signal_icon_tint_secondary"
tools:text="30 mins" tools:text="Now"
android:singleLine="true"/> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/conversation_list_item_name"
app:layout_constraintBottom_toBottomOf="@id/conversation_list_item_name"/>
<TextView android:id="@+id/archived" <TextView
android:id="@+id/conversation_list_item_archived"
style="@style/Signal.Text.Caption"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/date"
android:layout_alignParentEnd="true"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:background="@drawable/archived_indicator_background"
android:paddingStart="6dp" android:paddingStart="6dp"
android:paddingEnd="6dp"
android:paddingTop="2dp" android:paddingTop="2dp"
android:paddingEnd="6dp"
android:paddingBottom="2dp" android:paddingBottom="2dp"
style="@style/Signal.Text.Caption"
android:text="@string/conversation_list_item_view__archived" android:text="@string/conversation_list_item_view__archived"
android:textColor="@color/core_white" android:textColor="@color/core_white"
android:background="@drawable/archived_indicator_background" /> app:layout_constraintTop_toTopOf="@id/conversation_list_item_status"
app:layout_constraintBottom_toBottomOf="@id/conversation_list_item_status"
app:layout_constraintEnd_toEndOf="parent"/>
<FrameLayout android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_below="@id/date"
android:layout_toStartOf="@id/archived"
android:layout_alignWithParentIfMissing="true">
<org.thoughtcrime.securesms.components.DeliveryStatusView <org.thoughtcrime.securesms.components.DeliveryStatusView
android:id="@+id/delivery_status" android:id="@+id/conversation_list_item_status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
app:iconColor="@color/signal_icon_tint_secondary"/> app:iconColor="@color/signal_icon_tint_secondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/conversation_list_item_summary"
app:layout_constraintBottom_toBottomOf="@id/conversation_list_item_summary"/>
</FrameLayout> <androidx.constraintlayout.widget.Barrier
android:id="@+id/conversation_list_item_metadata_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="conversation_list_item_status,conversation_list_item_archived,conversation_list_item_date"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/conversation_list_item_status_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="conversation_list_item_status,conversation_list_item_thumbnail"/>
</RelativeLayout>
</org.thoughtcrime.securesms.conversationlist.ConversationListItem> </org.thoughtcrime.securesms.conversationlist.ConversationListItem>