mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-23 16:19:54 +01:00
[android] address review comments for displaying multiple images
This commit is contained in:
@@ -33,8 +33,7 @@ class ConversationMessageViewHolder extends ConversationItemViewHolder {
|
|||||||
// image list
|
// image list
|
||||||
RecyclerView list = v.findViewById(R.id.imageList);
|
RecyclerView list = v.findViewById(R.id.imageList);
|
||||||
list.setRecycledViewPool(imageViewPool);
|
list.setRecycledViewPool(imageViewPool);
|
||||||
adapter =
|
adapter = new ImageAdapter(v.getContext(), listener);
|
||||||
new ImageAdapter(v.getContext(), imageItemDecoration, listener);
|
|
||||||
list.setAdapter(adapter);
|
list.setAdapter(adapter);
|
||||||
list.addItemDecoration(imageItemDecoration);
|
list.addItemDecoration(imageItemDecoration);
|
||||||
|
|
||||||
|
|||||||
@@ -19,36 +19,35 @@ import java.util.List;
|
|||||||
|
|
||||||
import static android.content.Context.WINDOW_SERVICE;
|
import static android.content.Context.WINDOW_SERVICE;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.isRtl;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ImageAdapter extends Adapter<ImageViewHolder> {
|
class ImageAdapter extends Adapter<ImageViewHolder> {
|
||||||
|
|
||||||
private final List<AttachmentItem> items = new ArrayList<>();
|
private final List<AttachmentItem> items = new ArrayList<>();
|
||||||
private final ConversationListener listener;
|
private final ConversationListener listener;
|
||||||
private final int imageSize, borderSize;
|
private final int imageSize;
|
||||||
private final int radiusBig, radiusSmall;
|
private final int radiusBig, radiusSmall;
|
||||||
private final boolean isRtl;
|
private final boolean isRtl;
|
||||||
@Nullable
|
@Nullable
|
||||||
private ConversationMessageItem conversationItem;
|
private ConversationMessageItem conversationItem;
|
||||||
|
|
||||||
public ImageAdapter(Context ctx, ImageItemDecoration imageItemDecoration,
|
ImageAdapter(Context ctx, ConversationListener listener) {
|
||||||
ConversationListener listener) {
|
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
borderSize = imageItemDecoration.getBorderSize();
|
|
||||||
imageSize = getImageSize(ctx);
|
imageSize = getImageSize(ctx);
|
||||||
Resources res = ctx.getResources();
|
Resources res = ctx.getResources();
|
||||||
radiusBig =
|
radiusBig =
|
||||||
res.getDimensionPixelSize(R.dimen.message_bubble_radius_big);
|
res.getDimensionPixelSize(R.dimen.message_bubble_radius_big);
|
||||||
radiusSmall =
|
radiusSmall =
|
||||||
res.getDimensionPixelSize(R.dimen.message_bubble_radius_small);
|
res.getDimensionPixelSize(R.dimen.message_bubble_radius_small);
|
||||||
isRtl = imageItemDecoration.isRtl();
|
isRtl = isRtl(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
|
public ImageViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
|
||||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
||||||
R.layout.list_item_image, viewGroup, false);
|
R.layout.list_item_image, viewGroup, false);
|
||||||
return new ImageViewHolder(v, imageSize, borderSize);
|
return new ImageViewHolder(v, imageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.briar.android.conversation;
|
package org.briarproject.briar.android.conversation;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
@@ -11,9 +10,8 @@ import android.view.View;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.util.UiUtils;
|
||||||
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_RTL;
|
|
||||||
import static org.briarproject.briar.android.conversation.ImageAdapter.isBottomRow;
|
import static org.briarproject.briar.android.conversation.ImageAdapter.isBottomRow;
|
||||||
import static org.briarproject.briar.android.conversation.ImageAdapter.isLeft;
|
import static org.briarproject.briar.android.conversation.ImageAdapter.isLeft;
|
||||||
import static org.briarproject.briar.android.conversation.ImageAdapter.isTopRow;
|
import static org.briarproject.briar.android.conversation.ImageAdapter.isTopRow;
|
||||||
@@ -22,24 +20,22 @@ import static org.briarproject.briar.android.conversation.ImageAdapter.singleInR
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ImageItemDecoration extends ItemDecoration {
|
class ImageItemDecoration extends ItemDecoration {
|
||||||
|
|
||||||
private final int realBorderSize, border;
|
private final int border;
|
||||||
private final boolean isRtl;
|
private final boolean isRtl;
|
||||||
|
|
||||||
public ImageItemDecoration(Context ctx) {
|
ImageItemDecoration(Context ctx) {
|
||||||
Resources res = ctx.getResources();
|
Resources res = ctx.getResources();
|
||||||
|
|
||||||
// for pixel perfection, add a pixel to the border if it has an odd size
|
// for pixel perfection, add a pixel to the border if it has an odd size
|
||||||
int b = res.getDimensionPixelSize(R.dimen.message_bubble_border);
|
int b = res.getDimensionPixelSize(R.dimen.message_bubble_border);
|
||||||
realBorderSize = b % 2 == 0 ? b : b + 1;;
|
int realBorderSize = b % 2 == 0 ? b : b + 1;
|
||||||
|
|
||||||
// we are applying half the border around the insides of each image
|
// we are applying half the border around the insides of each image
|
||||||
// to prevent differently sized images looking slightly broken
|
// to prevent differently sized images looking slightly broken
|
||||||
border = realBorderSize / 2;
|
border = realBorderSize / 2;
|
||||||
|
|
||||||
// find out if we are showing a RTL language
|
// find out if we are showing a RTL language
|
||||||
Configuration config = res.getConfiguration();
|
isRtl = UiUtils.isRtl(ctx);
|
||||||
isRtl = SDK_INT >= 17 &&
|
|
||||||
config.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,19 +44,11 @@ class ImageItemDecoration extends ItemDecoration {
|
|||||||
if (state.getItemCount() == 1) return;
|
if (state.getItemCount() == 1) return;
|
||||||
int pos = parent.getChildAdapterPosition(view);
|
int pos = parent.getChildAdapterPosition(view);
|
||||||
int num = state.getItemCount();
|
int num = state.getItemCount();
|
||||||
boolean left = isLeft(pos) ^ isRtl;
|
boolean start = isLeft(pos) ^ isRtl;
|
||||||
outRect.top = isTopRow(pos) ? 0 : border;
|
outRect.top = isTopRow(pos) ? 0 : border;
|
||||||
outRect.left = left ? 0 : border;
|
outRect.left = start ? 0 : border;
|
||||||
outRect.right = left && !singleInRow(pos, num) ? border : 0;
|
outRect.right = start && !singleInRow(pos, num) ? border : 0;
|
||||||
outRect.bottom = isBottomRow(pos, num) ? 0 : border;
|
outRect.bottom = isBottomRow(pos, num) ? 0 : border;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBorderSize() {
|
|
||||||
return realBorderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRtl() {
|
|
||||||
return isRtl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,12 @@ class ImageViewHolder extends ViewHolder {
|
|||||||
private static final int ERROR_RES = R.drawable.ic_image_broken;
|
private static final int ERROR_RES = R.drawable.ic_image_broken;
|
||||||
|
|
||||||
protected final ImageView imageView;
|
protected final ImageView imageView;
|
||||||
private final int imageSize, borderSize;
|
private final int imageSize;
|
||||||
|
|
||||||
public ImageViewHolder(View v, int imageSize, int borderSize) {
|
ImageViewHolder(View v, int imageSize) {
|
||||||
super(v);
|
super(v);
|
||||||
imageView = v.findViewById(R.id.imageView);
|
imageView = v.findViewById(R.id.imageView);
|
||||||
this.imageSize = imageSize;
|
this.imageSize = imageSize;
|
||||||
this.borderSize = borderSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(AttachmentItem attachment, Radii r, boolean single,
|
void bind(AttachmentItem attachment, Radii r, boolean single,
|
||||||
@@ -49,9 +48,7 @@ class ImageViewHolder extends ViewHolder {
|
|||||||
private void setImageViewDimensions(AttachmentItem a, boolean single,
|
private void setImageViewDimensions(AttachmentItem a, boolean single,
|
||||||
boolean needsStretch) {
|
boolean needsStretch) {
|
||||||
LayoutParams params = (LayoutParams) imageView.getLayoutParams();
|
LayoutParams params = (LayoutParams) imageView.getLayoutParams();
|
||||||
// actual image size will shrink half the border
|
int width = needsStretch ? imageSize * 2 : imageSize;
|
||||||
int stretchSize = (imageSize - borderSize / 2) * 2 + borderSize;
|
|
||||||
int width = needsStretch ? stretchSize : imageSize;
|
|
||||||
params.width = single ? a.getThumbnailWidth() : width;
|
params.width = single ? a.getThumbnailWidth() : width;
|
||||||
params.height = single ? a.getThumbnailHeight() : imageSize;
|
params.height = single ? a.getThumbnailHeight() : imageSize;
|
||||||
params.setFullSpan(!single && needsStretch);
|
params.setFullSpan(!single && needsStretch);
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ public class ImageViewModel extends AndroidViewModel {
|
|||||||
@IoExecutor
|
@IoExecutor
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
|
|
||||||
private MutableLiveData<Boolean> saveState = new MutableLiveData<>();
|
private final MutableLiveData<Boolean> saveState = new MutableLiveData<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ImageViewModel(Application application,
|
ImageViewModel(Application application,
|
||||||
MessagingManager messagingManager,
|
MessagingManager messagingManager,
|
||||||
@DatabaseExecutor Executor dbExecutor,
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
@IoExecutor Executor ioExecutor) {
|
@IoExecutor Executor ioExecutor) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
|||||||
import static android.os.Build.MANUFACTURER;
|
import static android.os.Build.MANUFACTURER;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS;
|
import static android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS;
|
||||||
|
import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_RTL;
|
||||||
import static android.support.v7.app.AppCompatDelegate.MODE_NIGHT_AUTO;
|
import static android.support.v7.app.AppCompatDelegate.MODE_NIGHT_AUTO;
|
||||||
import static android.support.v7.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
import static android.support.v7.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||||
import static android.support.v7.app.AppCompatDelegate.MODE_NIGHT_NO;
|
import static android.support.v7.app.AppCompatDelegate.MODE_NIGHT_NO;
|
||||||
@@ -354,4 +355,10 @@ public class UiUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isRtl(Context ctx) {
|
||||||
|
if (SDK_INT < 17) return false;
|
||||||
|
return ctx.getResources().getConfiguration().getLayoutDirection() ==
|
||||||
|
LAYOUT_DIRECTION_RTL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user