Turn DelveryStatusView into a custom AppCompatImageView.

This commit is contained in:
Alex Hart
2023-06-21 16:28:32 -03:00
committed by Nicholas Tinsley
parent 71981e8a27
commit 1ad338ce31
2 changed files with 110 additions and 90 deletions

View File

@@ -2,26 +2,31 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import org.signal.core.util.logging.Log;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import org.signal.core.util.DimensionUnit;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.ViewUtil;
public class DeliveryStatusView extends FrameLayout {
public class DeliveryStatusView extends AppCompatImageView {
private static final String TAG = Log.tag(DeliveryStatusView.class);
private static final String STATE_KEY = "DeliveryStatusView.STATE";
private static final String ROOT_KEY = "DeliveryStatusView.ROOT";
private final int horizontalPadding = (int) DimensionUnit.DP.toPixels(2);
private final RotateAnimation rotationAnimation;
private final ImageView pendingIndicator;
private final ImageView sentIndicator;
private final ImageView deliveredIndicator;
private final ImageView readIndicator;
private State state = State.NONE;
public DeliveryStatusView(Context context) {
this(context, null);
@@ -34,13 +39,6 @@ public class DeliveryStatusView extends FrameLayout {
public DeliveryStatusView(final Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.delivery_status_view, this);
this.deliveredIndicator = findViewById(R.id.delivered_indicator);
this.sentIndicator = findViewById(R.id.sent_indicator);
this.pendingIndicator = findViewById(R.id.pending_indicator);
this.readIndicator = findViewById(R.id.read_indicator);
rotationAnimation = new RotateAnimation(0, 360f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
@@ -53,56 +51,122 @@ public class DeliveryStatusView extends FrameLayout {
setTint(typedArray.getColor(R.styleable.DeliveryStatusView_iconColor, getResources().getColor(R.color.core_white)));
typedArray.recycle();
}
setNone();
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle stateBundle = (Bundle) state;
State s = State.fromCode(stateBundle.getInt(STATE_KEY, State.NONE.code));
switch (s) {
case NONE:
setNone();
break;
case PENDING:
setPending();
break;
case SENT:
setSent();
break;
case DELIVERED:
setDelivered();
break;
case READ:
setRead();
break;
}
Parcelable root = stateBundle.getParcelable(ROOT_KEY);
super.onRestoreInstanceState(root);
} else {
super.onRestoreInstanceState(state);
}
}
@Override
protected @Nullable Parcelable onSaveInstanceState() {
Parcelable root = super.onSaveInstanceState();
Bundle stateBundle = new Bundle();
stateBundle.putParcelable(ROOT_KEY, root);
stateBundle.putInt(STATE_KEY, state.code);
return stateBundle;
}
public void setNone() {
this.setVisibility(View.GONE);
state = State.NONE;
setVisibility(View.GONE);
}
public boolean isPending() {
return pendingIndicator.getVisibility() == View.VISIBLE;
return state == State.PENDING;
}
public void setPending() {
this.setVisibility(View.VISIBLE);
pendingIndicator.setVisibility(View.VISIBLE);
pendingIndicator.startAnimation(rotationAnimation);
sentIndicator.setVisibility(View.GONE);
deliveredIndicator.setVisibility(View.GONE);
readIndicator.setVisibility(View.GONE);
state = State.PENDING;
setVisibility(View.VISIBLE);
ViewUtil.setPaddingStart(this, 0);
ViewUtil.setPaddingEnd(this, horizontalPadding);
setImageResource(R.drawable.ic_delivery_status_sending);
startAnimation(rotationAnimation);
}
public void setSent() {
this.setVisibility(View.VISIBLE);
pendingIndicator.setVisibility(View.GONE);
pendingIndicator.clearAnimation();
sentIndicator.setVisibility(View.VISIBLE);
deliveredIndicator.setVisibility(View.GONE);
readIndicator.setVisibility(View.GONE);
state = State.SENT;
setVisibility(View.VISIBLE);
ViewUtil.setPaddingStart(this, horizontalPadding);
ViewUtil.setPaddingEnd(this, 0);
clearAnimation();
setImageResource(R.drawable.ic_delivery_status_sent);
}
public void setDelivered() {
this.setVisibility(View.VISIBLE);
pendingIndicator.setVisibility(View.GONE);
pendingIndicator.clearAnimation();
sentIndicator.setVisibility(View.GONE);
deliveredIndicator.setVisibility(View.VISIBLE);
readIndicator.setVisibility(View.GONE);
state = State.DELIVERED;
setVisibility(View.VISIBLE);
ViewUtil.setPaddingStart(this, horizontalPadding);
ViewUtil.setPaddingEnd(this, 0);
clearAnimation();
setImageResource(R.drawable.ic_delivery_status_delivered);
}
public void setRead() {
this.setVisibility(View.VISIBLE);
pendingIndicator.setVisibility(View.GONE);
pendingIndicator.clearAnimation();
sentIndicator.setVisibility(View.GONE);
deliveredIndicator.setVisibility(View.GONE);
readIndicator.setVisibility(View.VISIBLE);
state = State.READ;
setVisibility(View.VISIBLE);
ViewUtil.setPaddingStart(this, horizontalPadding);
ViewUtil.setPaddingEnd(this, 0);
clearAnimation();
setImageResource(R.drawable.ic_delivery_status_read);
}
public void setTint(int color) {
pendingIndicator.setColorFilter(color);
deliveredIndicator.setColorFilter(color);
sentIndicator.setColorFilter(color);
readIndicator.setColorFilter(color);
setColorFilter(color);
}
private enum State {
NONE(0),
PENDING(1),
SENT(2),
DELIVERED(3),
READ(4);
final int code;
State(int code) {
this.code = code;
}
static State fromCode(int code) {
for (State state : State.values()) {
if (state.code == code) {
return state;
}
}
return NONE;
}
}
}

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true">
<ImageView
android:id="@+id/pending_indicator"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_marginEnd="2dp"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_delivery_status_sending"
android:visibility="gone" />
<ImageView android:id="@+id/sent_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_delivery_status_sent"
android:paddingStart="2dp"
android:visibility="gone"
android:contentDescription="@string/conversation_item_sent__delivered_description" />
<ImageView android:id="@+id/delivered_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_delivery_status_delivered"
android:paddingStart="2dp"
android:visibility="gone"
android:contentDescription="@string/conversation_item_sent__delivered_description"
tools:visibility="gone"/>
<ImageView android:id="@+id/read_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:src="@drawable/ic_delivery_status_read"
android:paddingStart="2dp"
android:visibility="gone"
android:contentDescription="@string/conversation_item_sent__message_read"
tools:visibility="visible"/>
</merge>