make avatar shape configurable (in code)
This commit is contained in:
parent
26d856e91f
commit
eb15dc1260
|
@ -10,6 +10,7 @@ import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
import im.conversations.android.R;
|
||||||
import im.conversations.android.database.model.AddressWithName;
|
import im.conversations.android.database.model.AddressWithName;
|
||||||
import im.conversations.android.database.model.AvatarWithAccount;
|
import im.conversations.android.database.model.AvatarWithAccount;
|
||||||
import im.conversations.android.ui.graphics.drawable.AvatarDrawable;
|
import im.conversations.android.ui.graphics.drawable.AvatarDrawable;
|
||||||
|
@ -59,9 +60,18 @@ public class AvatarFetcher {
|
||||||
LOGGER.info("ImageView reference was gone after fetching avatar");
|
LOGGER.info("ImageView reference was gone after fetching avatar");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final var resources = imageView.getResources();
|
||||||
final var roundedBitmapDrawable =
|
final var roundedBitmapDrawable =
|
||||||
RoundedBitmapDrawableFactory.create(imageView.getResources(), result);
|
RoundedBitmapDrawableFactory.create(resources, result);
|
||||||
roundedBitmapDrawable.setCircular(true);
|
final boolean circular = resources.getBoolean(R.bool.avatar_chat_overview_circular);
|
||||||
|
if (circular) {
|
||||||
|
roundedBitmapDrawable.setCircular(true);
|
||||||
|
} else {
|
||||||
|
final float radius =
|
||||||
|
resources.getDimension(R.dimen.avatar_chat_overview_radius)
|
||||||
|
/ resources.getDimension(R.dimen.avatar_chat_overview_size);
|
||||||
|
roundedBitmapDrawable.setCornerRadius(result.getWidth() * radius);
|
||||||
|
}
|
||||||
imageView.setImageDrawable(roundedBitmapDrawable);
|
imageView.setImageDrawable(roundedBitmapDrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import com.google.android.material.elevation.SurfaceColors;
|
import com.google.android.material.elevation.SurfaceColors;
|
||||||
|
@ -44,17 +45,22 @@ public class AvatarDrawable extends ColorDrawable {
|
||||||
private final int intrinsicWidth;
|
private final int intrinsicWidth;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
private final boolean circular;
|
||||||
|
private final int roundedCornerRadius;
|
||||||
|
|
||||||
public AvatarDrawable(final Context context, final AddressWithName addressWithName) {
|
public AvatarDrawable(final Context context, final AddressWithName addressWithName) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
final String name = addressWithName.name;
|
final String name = addressWithName.name;
|
||||||
final Jid key = addressWithName.address;
|
|
||||||
this.paint = getPaint(addressWithName.address);
|
this.paint = getPaint(addressWithName.address);
|
||||||
this.textPaint = getTextPaint();
|
this.textPaint = getTextPaint();
|
||||||
final Matcher matcher = LETTER_PATTERN.matcher(Strings.nullToEmpty(name));
|
final Matcher matcher = LETTER_PATTERN.matcher(Strings.nullToEmpty(name));
|
||||||
this.letter = matcher.find() ? matcher.group().toUpperCase(Locale.ROOT) : null;
|
this.letter = matcher.find() ? matcher.group().toUpperCase(Locale.ROOT) : null;
|
||||||
|
final var resources = context.getResources();
|
||||||
final int avatarDrawableSize =
|
final int avatarDrawableSize =
|
||||||
context.getResources().getDimensionPixelSize(R.dimen.avatar_drawable_size);
|
resources.getDimensionPixelSize(R.dimen.avatar_chat_overview_size);
|
||||||
|
this.circular = resources.getBoolean(R.bool.avatar_chat_overview_circular);
|
||||||
|
this.roundedCornerRadius =
|
||||||
|
resources.getDimensionPixelSize(R.dimen.avatar_chat_overview_radius);
|
||||||
this.intrinsicHeight = avatarDrawableSize;
|
this.intrinsicHeight = avatarDrawableSize;
|
||||||
this.intrinsicWidth = avatarDrawableSize;
|
this.intrinsicWidth = avatarDrawableSize;
|
||||||
}
|
}
|
||||||
|
@ -78,16 +84,25 @@ public class AvatarDrawable extends ColorDrawable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(final Canvas canvas) {
|
public void draw(final Canvas canvas) {
|
||||||
final float midX = getBounds().width() / 2.0f;
|
|
||||||
final float midY = getBounds().height() / 2.0f;
|
|
||||||
final float radius = Math.min(getBounds().width(), getBounds().height()) / 2.0f;
|
final float radius = Math.min(getBounds().width(), getBounds().height()) / 2.0f;
|
||||||
textPaint.setTextSize(radius);
|
this.textPaint.setTextSize(radius);
|
||||||
final Rect r = new Rect();
|
final Rect r = new Rect();
|
||||||
canvas.getClipBounds(r);
|
canvas.getClipBounds(r);
|
||||||
final int cHeight = r.height();
|
final int cHeight = r.height();
|
||||||
final int cWidth = r.width();
|
final int cWidth = r.width();
|
||||||
// TODO if we ever want to do rounded corners we can use drawRoundRect()
|
final var roundedSquareRadius =
|
||||||
canvas.drawCircle(midX, midY, radius, paint);
|
context.getResources().getDimensionPixelSize(R.dimen.avatar_chat_overview_radius);
|
||||||
|
if (this.circular) {
|
||||||
|
final float midX = getBounds().width() / 2.0f;
|
||||||
|
final float midY = getBounds().height() / 2.0f;
|
||||||
|
canvas.drawCircle(midX, midY, radius, paint);
|
||||||
|
} else {
|
||||||
|
canvas.drawRoundRect(
|
||||||
|
new RectF(0, 0, getBounds().width(), getBounds().height()),
|
||||||
|
roundedSquareRadius,
|
||||||
|
roundedSquareRadius,
|
||||||
|
paint);
|
||||||
|
}
|
||||||
if (letter == null) {
|
if (letter == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package im.conversations.android.xmpp.manager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.media.ThumbnailUtils;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.hash.Hashing;
|
import com.google.common.hash.Hashing;
|
||||||
|
@ -102,7 +103,12 @@ public class AvatarManager extends AbstractManager {
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
getAvatar(address, type, id),
|
getAvatar(address, type, id),
|
||||||
bytes -> {
|
bytes -> {
|
||||||
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
final var sourceBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||||
|
final var size = Math.min(sourceBitmap.getHeight(), sourceBitmap.getWidth());
|
||||||
|
// return a square version of the avatar. we are not displaying the rest and can
|
||||||
|
// save the bytes plus the corner radius calculation in AvatarFetcher requires a
|
||||||
|
// square
|
||||||
|
return ThumbnailUtils.extractThumbnail(sourceBitmap, size, size);
|
||||||
},
|
},
|
||||||
CPU_EXECUTOR);
|
CPU_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
android:layout_width="@dimen/avatar_drawable_size"
|
android:layout_width="@dimen/avatar_chat_overview_size"
|
||||||
android:layout_height="@dimen/avatar_drawable_size"
|
android:layout_height="@dimen/avatar_chat_overview_size"
|
||||||
android:layout_margin="16dp"
|
android:layout_marginStart="16dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
5
app/src/main/res/values/avatars.xml
Normal file
5
app/src/main/res/values/avatars.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<resources>
|
||||||
|
<dimen name="avatar_chat_overview_size">40dp</dimen>
|
||||||
|
<bool name="avatar_chat_overview_circular">false</bool>
|
||||||
|
<dimen name="avatar_chat_overview_radius">10dp</dimen>
|
||||||
|
</resources>
|
|
@ -8,5 +8,4 @@
|
||||||
<dimen name="in_call_fab_margin">8dp</dimen>
|
<dimen name="in_call_fab_margin">8dp</dimen>
|
||||||
<dimen name="in_call_fab_margin_center">12dp</dimen>
|
<dimen name="in_call_fab_margin_center">12dp</dimen>
|
||||||
<dimen name="publish_avatar_size">96dp</dimen>
|
<dimen name="publish_avatar_size">96dp</dimen>
|
||||||
<dimen name="avatar_drawable_size">40dp</dimen>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue