Commit 1e2c17b1 authored by akwizgran's avatar akwizgran

Merge branch '1242-display-image-attachments-multiple' into 'master'

Swipe left/right in image screen for images from same message

See merge request !1012
parents 87377666 a9949660
Pipeline #2904 passed with stage
in 10 minutes and 45 seconds
...@@ -20,6 +20,7 @@ import org.briarproject.briar.android.contact.ContactModule; ...@@ -20,6 +20,7 @@ import org.briarproject.briar.android.contact.ContactModule;
import org.briarproject.briar.android.conversation.AliasDialogFragment; import org.briarproject.briar.android.conversation.AliasDialogFragment;
import org.briarproject.briar.android.conversation.ConversationActivity; import org.briarproject.briar.android.conversation.ConversationActivity;
import org.briarproject.briar.android.conversation.ImageActivity; import org.briarproject.briar.android.conversation.ImageActivity;
import org.briarproject.briar.android.conversation.ImageFragment;
import org.briarproject.briar.android.forum.CreateForumActivity; import org.briarproject.briar.android.forum.CreateForumActivity;
import org.briarproject.briar.android.forum.ForumActivity; import org.briarproject.briar.android.forum.ForumActivity;
import org.briarproject.briar.android.forum.ForumListFragment; import org.briarproject.briar.android.forum.ForumListFragment;
...@@ -218,4 +219,6 @@ public interface ActivityComponent { ...@@ -218,4 +219,6 @@ public interface ActivityComponent {
void inject(AliasDialogFragment aliasDialogFragment); void inject(AliasDialogFragment aliasDialogFragment);
void inject(ImageFragment imageFragment);
} }
...@@ -2,6 +2,7 @@ package org.briarproject.briar.android.conversation; ...@@ -2,6 +2,7 @@ package org.briarproject.briar.android.conversation;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.Nullable;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
...@@ -111,4 +112,10 @@ public class AttachmentItem implements Parcelable { ...@@ -111,4 +112,10 @@ public class AttachmentItem implements Parcelable {
dest.writeByte((byte) (hasError ? 1 : 0)); dest.writeByte((byte) (hasError ? 1 : 0));
} }
@Override
public boolean equals(@Nullable Object o) {
return o instanceof AttachmentItem &&
messageId.equals(((AttachmentItem) o).messageId);
}
} }
...@@ -121,8 +121,9 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; ...@@ -121,8 +121,9 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_IMAGE_ATTACHMENTS; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_IMAGE_ATTACHMENTS;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ATTACH_IMAGE; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ATTACH_IMAGE;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION;
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT; import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT_POSITION;
import static org.briarproject.briar.android.conversation.ImageActivity.DATE; import static org.briarproject.briar.android.conversation.ImageActivity.DATE;
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENTS;
import static org.briarproject.briar.android.conversation.ImageActivity.NAME; import static org.briarproject.briar.android.conversation.ImageActivity.NAME;
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE; import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName; import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName;
...@@ -812,8 +813,11 @@ public class ConversationActivity extends BriarActivity ...@@ -812,8 +813,11 @@ public class ConversationActivity extends BriarActivity
} else { } else {
name = getString(R.string.you); name = getString(R.string.you);
} }
ArrayList<AttachmentItem> attachments =
new ArrayList<>(messageItem.getAttachments());
Intent i = new Intent(this, ImageActivity.class); Intent i = new Intent(this, ImageActivity.class);
i.putExtra(ATTACHMENT, item); i.putParcelableArrayListExtra(ATTACHMENTS, attachments);
i.putExtra(ATTACHMENT_POSITION, attachments.indexOf(item));
i.putExtra(NAME, name); i.putExtra(NAME, name);
i.putExtra(DATE, messageItem.getTime()); i.putExtra(DATE, messageItem.getTime());
if (SDK_INT >= 23) { if (SDK_INT >= 23) {
......
...@@ -4,15 +4,18 @@ import android.arch.lifecycle.ViewModelProvider; ...@@ -4,15 +4,18 @@ import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.support.design.widget.AppBarLayout; import android.support.design.widget.AppBarLayout;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog.Builder; import android.support.v7.app.AlertDialog.Builder;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.transition.Fade; import android.transition.Fade;
...@@ -20,23 +23,18 @@ import android.transition.Transition; ...@@ -20,23 +23,18 @@ import android.transition.Transition;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window; import android.view.Window;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.github.chrisbanes.photoview.PhotoView;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.conversation.glide.GlideApp;
import org.briarproject.briar.android.view.PullDownLayout; import org.briarproject.briar.android.view.PullDownLayout;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -53,16 +51,15 @@ import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; ...@@ -53,16 +51,15 @@ import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.widget.ImageView.ScaleType.FIT_START;
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SAVE_ATTACHMENT; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SAVE_ATTACHMENT;
import static org.briarproject.briar.android.util.UiUtils.formatDateAbsolute; import static org.briarproject.briar.android.util.UiUtils.formatDateAbsolute;
public class ImageActivity extends BriarActivity public class ImageActivity extends BriarActivity
implements PullDownLayout.Callback { implements PullDownLayout.Callback, OnGlobalLayoutListener {
final static String ATTACHMENT = "attachment"; final static String ATTACHMENTS = "attachments";
final static String ATTACHMENT_POSITION = "position";
final static String NAME = "name"; final static String NAME = "name";
final static String DATE = "date"; final static String DATE = "date";
...@@ -72,8 +69,8 @@ public class ImageActivity extends BriarActivity ...@@ -72,8 +69,8 @@ public class ImageActivity extends BriarActivity
private ImageViewModel viewModel; private ImageViewModel viewModel;
private PullDownLayout layout; private PullDownLayout layout;
private AppBarLayout appBarLayout; private AppBarLayout appBarLayout;
private PhotoView photoView; private ViewPager viewPager;
private AttachmentItem attachment; private List<AttachmentItem> attachments;
@Override @Override
public void injectActivity(ActivityComponent component) { public void injectActivity(ActivityComponent component) {
...@@ -102,6 +99,7 @@ public class ImageActivity extends BriarActivity ...@@ -102,6 +99,7 @@ public class ImageActivity extends BriarActivity
layout = findViewById(R.id.layout); layout = findViewById(R.id.layout);
layout.getBackground().setAlpha(255); layout.getBackground().setAlpha(255);
layout.setCallback(this); layout.setCallback(this);
layout.getViewTreeObserver().addOnGlobalLayoutListener(this);
// Status Bar // Status Bar
if (SDK_INT >= 21) { if (SDK_INT >= 21) {
...@@ -118,59 +116,29 @@ public class ImageActivity extends BriarActivity ...@@ -118,59 +116,29 @@ public class ImageActivity extends BriarActivity
TextView dateView = toolbar.findViewById(R.id.dateView); TextView dateView = toolbar.findViewById(R.id.dateView);
// Intent Extras // Intent Extras
attachment = getIntent().getParcelableExtra(ATTACHMENT); Intent i = getIntent();
String name = getIntent().getStringExtra(NAME); attachments = i.getParcelableArrayListExtra(ATTACHMENTS);
long time = getIntent().getLongExtra(DATE, 0); int position = i.getIntExtra(ATTACHMENT_POSITION, -1);
if (position == -1) throw new IllegalStateException();
String name = i.getStringExtra(NAME);
long time = i.getLongExtra(DATE, 0);
String date = formatDateAbsolute(this, time); String date = formatDateAbsolute(this, time);
contactName.setText(name); contactName.setText(name);
dateView.setText(date); dateView.setText(date);
// Image View // Set up image ViewPager
photoView = findViewById(R.id.photoView); viewPager = findViewById(R.id.viewPager);
ImagePagerAdapter pagerAdapter =
new ImagePagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(position);
if (SDK_INT >= 16) { if (SDK_INT >= 16) {
photoView.setOnClickListener(view -> toggleSystemUi()); viewModel.getOnImageClicked().observe(this, this::onImageClicked);
window.getDecorView().setSystemUiVisibility( window.getDecorView().setSystemUiVisibility(
SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_STABLE |
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} }
// Request Listener
RequestListener<Drawable> listener = new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e,
Object model, Target<Drawable> target,
boolean isFirstResource) {
supportStartPostponedEnterTransition();
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model,
Target<Drawable> target, DataSource dataSource,
boolean isFirstResource) {
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
// set transition name only when not animatable,
// because the animation won't start otherwise
photoView.setTransitionName(
attachment.getTransitionName());
}
// Move image to the top if overlapping toolbar
if (isOverlappingToolbar(resource)) {
photoView.setScaleType(FIT_START);
}
supportStartPostponedEnterTransition();
return false;
}
};
// Load Image
GlideApp.with(this)
.load(attachment)
.diskCacheStrategy(NONE)
.error(R.drawable.ic_image_broken)
.dontTransform()
.addListener(listener)
.into(photoView);
} }
@Override @Override
...@@ -193,11 +161,23 @@ public class ImageActivity extends BriarActivity ...@@ -193,11 +161,23 @@ public class ImageActivity extends BriarActivity
} }
} }
@Override
public void onGlobalLayout() {
viewModel.setToolbarPosition(
appBarLayout.getTop(), appBarLayout.getBottom()
);
if (SDK_INT >= 16) {
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
@Override @Override
protected void onActivityResult(int request, int result, Intent data) { protected void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data); super.onActivityResult(request, result, data);
if (request == REQUEST_SAVE_ATTACHMENT && result == RESULT_OK) { if (request == REQUEST_SAVE_ATTACHMENT && result == RESULT_OK) {
viewModel.saveImage(attachment, data.getData()); viewModel.saveImage(getVisibleAttachment(), data.getData());
} }
} }
...@@ -225,6 +205,14 @@ public class ImageActivity extends BriarActivity ...@@ -225,6 +205,14 @@ public class ImageActivity extends BriarActivity
supportFinishAfterTransition(); supportFinishAfterTransition();
} }
@RequiresApi(api = 16)
private void onImageClicked(@Nullable Boolean clicked) {
if (clicked != null && clicked) {
toggleSystemUi();
viewModel.onOnImageClickSeen();
}
}
@RequiresApi(api = 16) @RequiresApi(api = 16)
private void toggleSystemUi() { private void toggleSystemUi() {
View decorView = getWindow().getDecorView(); View decorView = getWindow().getDecorView();
...@@ -259,29 +247,13 @@ public class ImageActivity extends BriarActivity ...@@ -259,29 +247,13 @@ public class ImageActivity extends BriarActivity
.start(); .start();
} }
private boolean isOverlappingToolbar(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
float widthPercentage = photoView.getWidth() / (float) width;
float heightPercentage = photoView.getHeight() / (float) height;
float scaleFactor = Math.min(widthPercentage, heightPercentage);
int realWidth = (int) (width * scaleFactor);
int realHeight = (int) (height * scaleFactor);
// return if photo doesn't use the full width,
// because it will be moved to the right otherwise
if (realWidth < photoView.getWidth()) return false;
int drawableTop = (photoView.getHeight() - realHeight) / 2;
return drawableTop < appBarLayout.getBottom() &&
drawableTop != appBarLayout.getTop();
}
private void showSaveImageDialog() { private void showSaveImageDialog() {
OnClickListener okListener = (dialog, which) -> { OnClickListener okListener = (dialog, which) -> {
if (SDK_INT >= 19) { if (SDK_INT >= 19) {
Intent intent = getCreationIntent(); Intent intent = getCreationIntent();
startActivityForResult(intent, REQUEST_SAVE_ATTACHMENT); startActivityForResult(intent, REQUEST_SAVE_ATTACHMENT);
} else { } else {
viewModel.saveImage(attachment); viewModel.saveImage(getVisibleAttachment());
} }
}; };
Builder builder = new Builder(this, R.style.BriarDialogTheme); Builder builder = new Builder(this, R.style.BriarDialogTheme);
...@@ -303,7 +275,7 @@ public class ImageActivity extends BriarActivity ...@@ -303,7 +275,7 @@ public class ImageActivity extends BriarActivity
String fileName = sdf.format(new Date()); String fileName = sdf.format(new Date());
Intent intent = new Intent(ACTION_CREATE_DOCUMENT); Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
intent.addCategory(CATEGORY_OPENABLE); intent.addCategory(CATEGORY_OPENABLE);
intent.setType(attachment.getMimeType()); intent.setType(getVisibleAttachment().getMimeType());
intent.putExtra(EXTRA_TITLE, fileName); intent.putExtra(EXTRA_TITLE, fileName);
return intent; return intent;
} }
...@@ -320,4 +292,26 @@ public class ImageActivity extends BriarActivity ...@@ -320,4 +292,26 @@ public class ImageActivity extends BriarActivity
viewModel.onSaveStateSeen(); viewModel.onSaveStateSeen();
} }
AttachmentItem getVisibleAttachment() {
return attachments.get(viewPager.getCurrentItem());
}
private class ImagePagerAdapter extends FragmentStatePagerAdapter {
private ImagePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return ImageFragment.newInstance(attachments.get(position));
}
@Override
public int getCount() {
return attachments.size();
}
}
} }
package org.briarproject.briar.android.conversation;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.github.chrisbanes.photoview.PhotoView;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.briar.android.conversation.glide.GlideApp;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.inject.Inject;
import static android.os.Build.VERSION.SDK_INT;
import static android.widget.ImageView.ScaleType.FIT_START;
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT_POSITION;
@MethodsNotNullByDefault
@ParametersAreNonnullByDefault
public class ImageFragment extends Fragment {
@Inject
ViewModelProvider.Factory viewModelFactory;
private AttachmentItem attachment;
private ImageViewModel viewModel;
private PhotoView photoView;
static ImageFragment newInstance(AttachmentItem a) {
ImageFragment f = new ImageFragment();
Bundle args = new Bundle();
args.putParcelable(ATTACHMENT_POSITION, a);
f.setArguments(args);
return f;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
BaseActivity a = (BaseActivity) requireNonNull(getActivity());
a.getActivityComponent().inject(this);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = requireNonNull(getArguments());
attachment = requireNonNull(args.getParcelable(ATTACHMENT_POSITION));
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_image, container,
false);
viewModel = ViewModelProviders.of(requireNonNull(getActivity()),
viewModelFactory).get(ImageViewModel.class);
photoView = v.findViewById(R.id.photoView);
photoView.setOnClickListener(view -> viewModel.clickImage());
// Request Listener
RequestListener<Drawable> listener = new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e,
Object model, Target<Drawable> target,
boolean isFirstResource) {
if (getActivity() != null)
getActivity().supportStartPostponedEnterTransition();
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model,
Target<Drawable> target, DataSource dataSource,
boolean isFirstResource) {
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
// set transition name only when not animatable,
// because the animation won't start otherwise
photoView.setTransitionName(
attachment.getTransitionName());
}
// Move image to the top if overlapping toolbar
if (viewModel.isOverlappingToolbar(photoView, resource)) {
photoView.setScaleType(FIT_START);
}
if (getActivity() != null)
getActivity().supportStartPostponedEnterTransition();
return false;
}
};
// Load Image
GlideApp.with(this)
.load(attachment)
.diskCacheStrategy(NONE)
.error(R.drawable.ic_image_broken)
.dontTransform()
.addListener(listener)
.into(photoView);
return v;
}
}
...@@ -4,9 +4,11 @@ import android.app.Application; ...@@ -4,9 +4,11 @@ import android.app.Application;
import android.arch.lifecycle.AndroidViewModel; import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData; import android.arch.lifecycle.MutableLiveData;
import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.view.View;
import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
...@@ -48,7 +50,10 @@ public class ImageViewModel extends AndroidViewModel { ...@@ -48,7 +50,10 @@ public class ImageViewModel extends AndroidViewModel {
@IoExecutor @IoExecutor
private final Executor ioExecutor; private final Executor ioExecutor;
private final MutableLiveData<Boolean> imageClicked =
new MutableLiveData<>();
private final MutableLiveData<Boolean> saveState = new MutableLiveData<>(); private final MutableLiveData<Boolean> saveState = new MutableLiveData<>();
private int toolbarTop, toolbarBottom;
@Inject @Inject
ImageViewModel(Application application, ImageViewModel(Application application,
...@@ -61,6 +66,45 @@ public class ImageViewModel extends AndroidViewModel { ...@@ -61,6 +66,45 @@ public class ImageViewModel extends AndroidViewModel {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
} }
void clickImage() {
imageClicked.setValue(true);
}
/**
* A LiveData that is true if the image was clicked,
* false if it wasn't.
*
* Call {@link #onOnImageClickSeen()} after consuming an update.
*/
LiveData<Boolean> getOnImageClicked() {
return imageClicked;
}
@UiThread
void onOnImageClickSeen() {
imageClicked.setValue(false);
}
void setToolbarPosition(int top, int bottom) {
toolbarTop = top;
toolbarBottom = bottom;
}
boolean isOverlappingToolbar(View screenView, Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
float widthPercentage = screenView.getWidth() / (float) width;
float heightPercentage = screenView.getHeight() / (float) height;
float scaleFactor = Math.min(widthPercentage, heightPercentage);
int realWidth = (int) (width * scaleFactor);
int realHeight = (int) (height * scaleFactor);
// return if image doesn't use the full width,
// because it will be moved to the right otherwise
if (realWidth < screenView.getWidth()) return false;
int drawableTop = (screenView.getHeight() - realHeight) / 2;
return drawableTop < toolbarBottom && drawableTop != toolbarTop;
}
/** /**
* A LiveData that is true if the image was saved, * A LiveData that is true if the image was saved,
* false if there was an error and null otherwise. * false if there was an error and null otherwise.
......
...@@ -8,12 +8,11 @@ ...@@ -8,12 +8,11 @@
android:background="@color/briar_black" android:background="@color/briar_black"
tools:context=".android.conversation.ImageActivity"> tools:context=".android.conversation.ImageActivity">
<com.github.chrisbanes.photoview.PhotoView <android.support.v4.view.ViewPager
android:id="@+id/photoView" android:id="@+id/viewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:ignore="ContentDescription" tools:background="@color/briar_green_light"/>
tools:srcCompat="@tools:sample/backgrounds/scenic"/>
<android.support.design.widget.AppBarLayout <android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout" android:id="@+id/appBarLayout"
......
<?xml version="1.0" encoding="utf-8"?>
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/photoView"
xmlns:android="http://schemas.android.com/apk/res/android"