568 lines
25 KiB
Java
568 lines
25 KiB
Java
package app.fedilab.android.mastodon.imageeditor;
|
|
|
|
|
|
import android.Manifest;
|
|
import android.content.Intent;
|
|
import android.content.pm.PackageManager;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BitmapFactory;
|
|
import android.graphics.Typeface;
|
|
import android.net.Uri;
|
|
import android.os.Build;
|
|
import android.os.Bundle;
|
|
import android.provider.MediaStore;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.animation.AnticipateOvershootInterpolator;
|
|
|
|
import androidx.activity.result.ActivityResultLauncher;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.appcompat.app.AlertDialog;
|
|
import androidx.constraintlayout.widget.ConstraintSet;
|
|
import androidx.core.app.ActivityCompat;
|
|
import androidx.core.content.ContextCompat;
|
|
import androidx.exifinterface.media.ExifInterface;
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.transition.ChangeBounds;
|
|
import androidx.transition.TransitionManager;
|
|
|
|
import com.canhub.cropper.CropImage;
|
|
import com.canhub.cropper.CropImageContract;
|
|
import com.canhub.cropper.CropImageContractOptions;
|
|
import com.canhub.cropper.CropImageOptions;
|
|
import com.canhub.cropper.CropImageView;
|
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
|
|
import app.fedilab.android.BuildConfig;
|
|
import app.fedilab.android.R;
|
|
import app.fedilab.android.databinding.ActivityEditImageBinding;
|
|
import app.fedilab.android.mastodon.client.entities.app.CachedBundle;
|
|
import app.fedilab.android.mastodon.helper.CirclesDrawingView;
|
|
import app.fedilab.android.mastodon.helper.Helper;
|
|
import app.fedilab.android.mastodon.imageeditor.base.BaseActivity;
|
|
import app.fedilab.android.mastodon.imageeditor.filters.FilterListener;
|
|
import app.fedilab.android.mastodon.imageeditor.filters.FilterViewAdapter;
|
|
import app.fedilab.android.mastodon.imageeditor.tools.EditingToolsAdapter;
|
|
import app.fedilab.android.mastodon.imageeditor.tools.ToolType;
|
|
import es.dmoral.toasty.Toasty;
|
|
import ja.burhanrashid52.photoeditor.OnPhotoEditorListener;
|
|
import ja.burhanrashid52.photoeditor.PhotoEditor;
|
|
import ja.burhanrashid52.photoeditor.PhotoFilter;
|
|
import ja.burhanrashid52.photoeditor.SaveSettings;
|
|
import ja.burhanrashid52.photoeditor.TextStyleBuilder;
|
|
import ja.burhanrashid52.photoeditor.ViewType;
|
|
import ja.burhanrashid52.photoeditor.shape.ShapeBuilder;
|
|
import ja.burhanrashid52.photoeditor.shape.ShapeType;
|
|
|
|
public class EditImageActivity extends BaseActivity implements OnPhotoEditorListener,
|
|
View.OnClickListener,
|
|
PropertiesBSFragment.Properties,
|
|
ShapeBSFragment.Properties,
|
|
EmojiBSFragment.EmojiListener, EditingToolsAdapter.OnItemSelected, FilterListener {
|
|
|
|
private static final int CAMERA_REQUEST = 52;
|
|
private static final int PICK_REQUEST = 53;
|
|
private final int STORE_REQUEST = 54;
|
|
private final EditingToolsAdapter mEditingToolsAdapter = new EditingToolsAdapter(this);
|
|
private final FilterViewAdapter mFilterViewAdapter = new FilterViewAdapter(this);
|
|
private final ConstraintSet mConstraintSet = new ConstraintSet();
|
|
PhotoEditor mPhotoEditor;
|
|
String path;
|
|
CropImageContractOptions cropImageContractOptions;
|
|
ActivityResultLauncher<CropImageContractOptions> cropImageContractOptionsActivityResultLauncher;
|
|
private PropertiesBSFragment mPropertiesBSFragment;
|
|
private ShapeBSFragment mShapeBSFragment;
|
|
private ShapeBuilder mShapeBuilder;
|
|
private EmojiBSFragment mEmojiBSFragment;
|
|
private boolean mIsFilterVisible;
|
|
private Uri uri;
|
|
private boolean exit;
|
|
private ActivityEditImageBinding binding;
|
|
|
|
private static int exifToDegrees(int exifOrientation) {
|
|
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
|
|
return 90;
|
|
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
|
|
return 180;
|
|
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
|
|
return 270;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
binding = ActivityEditImageBinding.inflate(getLayoutInflater());
|
|
setContentView(binding.getRoot());
|
|
Bundle b = getIntent().getExtras();
|
|
if (getSupportActionBar() != null)
|
|
getSupportActionBar().hide();
|
|
|
|
if (b != null)
|
|
path = b.getString("imageUri", null);
|
|
|
|
if (path == null) {
|
|
finish();
|
|
}
|
|
uri = Uri.parse("file://" + path);
|
|
exit = false;
|
|
initViews();
|
|
mPropertiesBSFragment = new PropertiesBSFragment();
|
|
mEmojiBSFragment = new EmojiBSFragment();
|
|
mShapeBSFragment = new ShapeBSFragment();
|
|
mEmojiBSFragment.setEmojiListener(this);
|
|
mPropertiesBSFragment.setPropertiesChangeListener(this);
|
|
mShapeBSFragment.setPropertiesChangeListener(this);
|
|
|
|
LinearLayoutManager llmTools = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
|
|
binding.rvConstraintTools.setLayoutManager(llmTools);
|
|
binding.rvConstraintTools.setAdapter(mEditingToolsAdapter);
|
|
|
|
LinearLayoutManager llmFilters = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
|
|
binding.rvFilterView.setLayoutManager(llmFilters);
|
|
binding.rvFilterView.setAdapter(mFilterViewAdapter);
|
|
|
|
Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");
|
|
|
|
mPhotoEditor = new PhotoEditor.Builder(this, binding.photoEditorView)
|
|
.setPinchTextScalable(true)
|
|
.setDefaultEmojiTypeface(mEmojiTypeFace)
|
|
.build(); // build photo editor sdk
|
|
|
|
mPhotoEditor.setOnPhotoEditorListener(this);
|
|
|
|
|
|
//Set Image Dynamically
|
|
try {
|
|
binding.photoEditorView.getSource().setImageURI(uri);
|
|
} catch (Exception e) {
|
|
Toasty.error(EditImageActivity.this, getString(R.string.toast_error)).show();
|
|
}
|
|
|
|
if (uri != null) {
|
|
try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
|
|
ExifInterface exif = new ExifInterface(inputStream);
|
|
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
|
|
int rotationInDegrees = exifToDegrees(rotation);
|
|
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
cropImageContractOptions = new CropImageContractOptions(uri, new CropImageOptions())
|
|
.setGuidelines(CropImageView.Guidelines.ON)
|
|
.setCropShape(CropImageView.CropShape.RECTANGLE)
|
|
.setAllowRotation(true)
|
|
.setAllowFlipping(true)
|
|
.setOutputCompressFormat(Bitmap.CompressFormat.PNG)
|
|
.setAllowCounterRotation(true)
|
|
.setImageSource(true, false)
|
|
.setScaleType(CropImageView.ScaleType.CENTER);
|
|
cropImageContractOptionsActivityResultLauncher = registerForActivityResult(
|
|
new CropImageContract(),
|
|
result -> {
|
|
if (result.isSuccessful()) {
|
|
Uri resultUri = result.getUriContent();
|
|
if (resultUri != null) {
|
|
binding.photoEditorView.getSource().setImageURI(resultUri);
|
|
if (uri != null && uri.getPath() != null) {
|
|
File fdelete = new File(uri.getPath());
|
|
if (fdelete.exists()) {
|
|
//noinspection ResultOfMethodCallIgnored
|
|
fdelete.delete();
|
|
}
|
|
}
|
|
uri = resultUri;
|
|
}
|
|
}
|
|
});
|
|
mPhotoEditor.setFilterEffect(PhotoFilter.NONE);
|
|
binding.send.setOnClickListener(v -> {
|
|
exit = true;
|
|
saveImage();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onRequestPermissionsResult(int requestCode,
|
|
@NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
if (requestCode == STORE_REQUEST) {// If request is cancelled, the result arrays are empty.
|
|
if (grantResults.length > 0
|
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
saveImage();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void initViews() {
|
|
binding.imgUndo.setOnClickListener(this);
|
|
binding.imgRedo.setOnClickListener(this);
|
|
binding.imgClose.setOnClickListener(this);
|
|
}
|
|
|
|
@Override
|
|
public void onEditTextChangeListener(final View rootView, String text, int colorCode) {
|
|
TextEditorDialogFragment textEditorDialogFragment =
|
|
TextEditorDialogFragment.show(this, text, colorCode);
|
|
textEditorDialogFragment.setOnTextEditorListener((inputText, newColorCode) -> {
|
|
final TextStyleBuilder styleBuilder = new TextStyleBuilder();
|
|
styleBuilder.withTextColor(newColorCode);
|
|
|
|
mPhotoEditor.editText(rootView, inputText, styleBuilder);
|
|
binding.txtCurrentTool.setText(R.string.label_text);
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onAddViewListener(ViewType viewType, int numberOfAddedViews) {
|
|
}
|
|
|
|
@Override
|
|
public void onRemoveViewListener(ViewType viewType, int numberOfAddedViews) {
|
|
}
|
|
|
|
@Override
|
|
public void onStartViewChangeListener(ViewType viewType) {
|
|
}
|
|
|
|
@Override
|
|
public void onStopViewChangeListener(ViewType viewType) {
|
|
}
|
|
|
|
@Override
|
|
public void onTouchSourceImage(MotionEvent event) {
|
|
}
|
|
|
|
@Override
|
|
public void onClick(View view) {
|
|
int id = view.getId();
|
|
if (id == R.id.imgUndo) {
|
|
mPhotoEditor.undo();
|
|
} else if (id == R.id.imgRedo) {
|
|
mPhotoEditor.redo();
|
|
} else if (id == R.id.imgClose) {
|
|
onBackPressed();
|
|
}
|
|
}
|
|
|
|
private void saveImage() {
|
|
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
showLoading(getString(R.string.saving));
|
|
File file = new File(path);
|
|
try {
|
|
//noinspection ResultOfMethodCallIgnored
|
|
file.createNewFile();
|
|
|
|
SaveSettings saveSettings = new SaveSettings.Builder()
|
|
.setClearViewsEnabled(true)
|
|
.setTransparencyEnabled(true)
|
|
.build();
|
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
|
if (ContextCompat.checkSelfPermission(EditImageActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
|
|
PackageManager.PERMISSION_GRANTED) {
|
|
ActivityCompat.requestPermissions(EditImageActivity.this,
|
|
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
|
STORE_REQUEST);
|
|
return;
|
|
}
|
|
}
|
|
|
|
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
|
|
@Override
|
|
public void onSuccess(@NonNull String imagePath) {
|
|
hideLoading();
|
|
showSnackbar(getString(R.string.image_saved));
|
|
binding.photoEditorView.getSource().setImageURI(Uri.fromFile(new File(imagePath)));
|
|
if (exit) {
|
|
Intent intentImage = new Intent(Helper.INTENT_SEND_MODIFIED_IMAGE);
|
|
Bundle args = new Bundle();
|
|
args.putString("imgpath", imagePath);
|
|
CirclesDrawingView.CircleArea circleArea = binding.focusCircle.getTouchedCircle();
|
|
if (circleArea != null) {
|
|
//Dimension of the editor containing the image
|
|
int pHeight = binding.photoEditorView.getHeight();
|
|
int pWidth = binding.photoEditorView.getWidth();
|
|
//Load the original image in a bitmap
|
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
|
options.inJustDecodeBounds = true;
|
|
BitmapFactory.decodeFile(new File(imagePath).getAbsolutePath(), options);
|
|
//Get height and width of the original image
|
|
int imageHeight = options.outHeight;
|
|
int imageWidth = options.outWidth;
|
|
|
|
//Evaluate the dimension of the image in the editor
|
|
int imgHeightInEditor;
|
|
int imgWidthInEditor;
|
|
//If the original image has its height greater than width => heights are equals
|
|
float focusX, focusY;
|
|
if (imageHeight > imageWidth) {
|
|
imgHeightInEditor = pHeight;
|
|
float ratio = (float) pHeight / (float) imageHeight;
|
|
imgWidthInEditor = (int) (pWidth * ratio);
|
|
} else { //Otherwise widths are equals
|
|
imgWidthInEditor = pWidth;
|
|
float ratio = (float) pWidth / (float) imageWidth;
|
|
imgHeightInEditor = (int) (pHeight * ratio);
|
|
}
|
|
focusY = (float) (circleArea.centerY * 2 - imgHeightInEditor / 2) / (float) imgHeightInEditor - 0.5f;
|
|
focusX = (float) (circleArea.centerX * 2 - imgWidthInEditor / 2) / (float) imgWidthInEditor - 0.5f;
|
|
if (focusX > 1) {
|
|
focusX = 1;
|
|
} else if (focusX < -1) {
|
|
focusX = -1;
|
|
}
|
|
if (focusY > 1) {
|
|
focusY = 1;
|
|
} else if (focusY < -1) {
|
|
focusY = -1;
|
|
}
|
|
args.putFloat("focusX", focusX);
|
|
args.putFloat("focusY", focusY);
|
|
}
|
|
new CachedBundle(EditImageActivity.this).insertBundle(args, Helper.getCurrentAccount(EditImageActivity.this), bundleId -> {
|
|
intentImage.putExtras(args);
|
|
intentImage.setPackage(BuildConfig.APPLICATION_ID);
|
|
sendBroadcast(intentImage);
|
|
finish();
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(@NonNull Exception exception) {
|
|
hideLoading();
|
|
showSnackbar(getString(R.string.save_image_failed));
|
|
}
|
|
});
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
hideLoading();
|
|
if (e.getMessage() != null) {
|
|
showSnackbar(e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
if (resultCode == RESULT_OK) {
|
|
ExifInterface exif;
|
|
int rotation;
|
|
int rotationInDegrees = 0;
|
|
if (data != null && data.getData() != null) {
|
|
try (InputStream inputStream = getContentResolver().openInputStream(data.getData())) {
|
|
assert inputStream != null;
|
|
exif = new ExifInterface(inputStream);
|
|
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
|
|
rotationInDegrees = exifToDegrees(rotation);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
switch (requestCode) {
|
|
case CAMERA_REQUEST:
|
|
if (data != null && data.getExtras() != null) {
|
|
mPhotoEditor.clearAllViews();
|
|
Bitmap photo = (Bitmap) data.getExtras().get("data");
|
|
binding.photoEditorView.getSource().setImageBitmap(photo);
|
|
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
|
|
}
|
|
break;
|
|
case PICK_REQUEST:
|
|
if (data != null && data.getData() != null) {
|
|
try {
|
|
mPhotoEditor.clearAllViews();
|
|
Uri uri = data.getData();
|
|
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
|
|
binding.photoEditorView.getSource().setImageBitmap(bitmap);
|
|
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
break;
|
|
case CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE:
|
|
if (data != null && data.getData() != null) {
|
|
CropImageContractOptions cropImageContractOptions = new CropImageContractOptions(data.getData(), new CropImageOptions())
|
|
.setGuidelines(CropImageView.Guidelines.ON)
|
|
.setCropShape(CropImageView.CropShape.RECTANGLE)
|
|
.setAllowRotation(true)
|
|
.setAllowFlipping(true)
|
|
.setOutputCompressFormat(Bitmap.CompressFormat.PNG)
|
|
.setAllowCounterRotation(true)
|
|
.setImageSource(true, false)
|
|
.setScaleType(CropImageView.ScaleType.CENTER);
|
|
ActivityResultLauncher<CropImageContractOptions> cropImageContractOptionsActivityResultLauncher = registerForActivityResult(
|
|
new CropImageContract(),
|
|
result -> {
|
|
if (result.isSuccessful()) {
|
|
Uri resultUri = result.getUriContent();
|
|
if (resultUri != null) {
|
|
binding.photoEditorView.getSource().setImageURI(resultUri);
|
|
if (uri != null && uri.getPath() != null) {
|
|
File fdelete = new File(uri.getPath());
|
|
if (fdelete.exists()) {
|
|
//noinspection ResultOfMethodCallIgnored
|
|
fdelete.delete();
|
|
}
|
|
}
|
|
uri = resultUri;
|
|
}
|
|
}
|
|
});
|
|
cropImageContractOptionsActivityResultLauncher.launch(cropImageContractOptions);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onColorChanged(int colorCode) {
|
|
mPhotoEditor.setShape(mShapeBuilder.withShapeColor(colorCode));
|
|
binding.txtCurrentTool.setText(R.string.label_brush);
|
|
}
|
|
|
|
@Override
|
|
public void onOpacityChanged(int opacity) {
|
|
mPhotoEditor.setShape(mShapeBuilder.withShapeOpacity(opacity));
|
|
binding.txtCurrentTool.setText(R.string.label_brush);
|
|
}
|
|
|
|
@Override
|
|
public void onShapeSizeChanged(int shapeSize) {
|
|
mPhotoEditor.setShape(mShapeBuilder.withShapeSize(shapeSize));
|
|
binding.txtCurrentTool.setText(R.string.label_brush);
|
|
}
|
|
|
|
@Override
|
|
public void onShapePicked(ShapeType shapeType) {
|
|
mPhotoEditor.setShape(mShapeBuilder.withShapeType(shapeType));
|
|
}
|
|
|
|
@Override
|
|
public void onEmojiClick(String emojiUnicode) {
|
|
mPhotoEditor.addEmoji(emojiUnicode);
|
|
binding.txtCurrentTool.setText(R.string.label_emoji);
|
|
}
|
|
|
|
private void showSaveDialog() {
|
|
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
|
|
builder.setMessage(getString(R.string.msg_save_image));
|
|
builder.setPositiveButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
|
builder.setNegativeButton(R.string.discard, (dialog, which) -> finish());
|
|
builder.create().show();
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onFilterSelected(PhotoFilter photoFilter) {
|
|
mPhotoEditor.setFilterEffect(photoFilter);
|
|
}
|
|
|
|
@Override
|
|
public void onToolSelected(ToolType toolType) {
|
|
binding.focusCircle.setVisibility(View.GONE);
|
|
switch (toolType) {
|
|
case SHAPE:
|
|
mPhotoEditor.setBrushDrawingMode(true);
|
|
mShapeBuilder = new ShapeBuilder();
|
|
mPhotoEditor.setShape(mShapeBuilder);
|
|
binding.txtCurrentTool.setText(R.string.label_shape);
|
|
showBottomSheetDialogFragment(mShapeBSFragment);
|
|
break;
|
|
case TEXT:
|
|
TextEditorDialogFragment textEditorDialogFragment = TextEditorDialogFragment.show(this);
|
|
textEditorDialogFragment.setOnTextEditorListener((inputText, colorCode) -> {
|
|
final TextStyleBuilder styleBuilder = new TextStyleBuilder();
|
|
styleBuilder.withTextColor(colorCode);
|
|
|
|
mPhotoEditor.addText(inputText, styleBuilder);
|
|
binding.txtCurrentTool.setText(R.string.label_text);
|
|
});
|
|
break;
|
|
case ERASER:
|
|
mPhotoEditor.brushEraser();
|
|
binding.txtCurrentTool.setText(R.string.label_eraser_mode);
|
|
break;
|
|
case FILTER:
|
|
binding.txtCurrentTool.setText(R.string.label_filter);
|
|
showFilter(true);
|
|
break;
|
|
case EMOJI:
|
|
showBottomSheetDialogFragment(mEmojiBSFragment);
|
|
break;
|
|
case BRUSH:
|
|
mPhotoEditor.setBrushDrawingMode(true);
|
|
binding.txtCurrentTool.setText(R.string.label_brush);
|
|
mPropertiesBSFragment.show(getSupportFragmentManager(), mPropertiesBSFragment.getTag());
|
|
break;
|
|
case CROP:
|
|
|
|
cropImageContractOptionsActivityResultLauncher.launch(cropImageContractOptions);
|
|
break;
|
|
case FOCUS:
|
|
binding.focusCircle.setVisibility(View.VISIBLE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void showBottomSheetDialogFragment(BottomSheetDialogFragment fragment) {
|
|
if (fragment == null || fragment.isAdded()) {
|
|
return;
|
|
}
|
|
fragment.show(getSupportFragmentManager(), fragment.getTag());
|
|
}
|
|
|
|
|
|
void showFilter(boolean isVisible) {
|
|
mIsFilterVisible = isVisible;
|
|
mConstraintSet.clone(binding.rootView);
|
|
|
|
if (isVisible) {
|
|
mConstraintSet.clear(binding.rvFilterView.getId(), ConstraintSet.START);
|
|
mConstraintSet.connect(binding.rvFilterView.getId(), ConstraintSet.START,
|
|
ConstraintSet.PARENT_ID, ConstraintSet.START);
|
|
mConstraintSet.connect(binding.rvFilterView.getId(), ConstraintSet.END,
|
|
ConstraintSet.PARENT_ID, ConstraintSet.END);
|
|
} else {
|
|
mConstraintSet.connect(binding.rvFilterView.getId(), ConstraintSet.START,
|
|
ConstraintSet.PARENT_ID, ConstraintSet.END);
|
|
mConstraintSet.clear(binding.rvFilterView.getId(), ConstraintSet.END);
|
|
}
|
|
|
|
ChangeBounds changeBounds = new ChangeBounds();
|
|
changeBounds.setDuration(350);
|
|
changeBounds.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
|
|
TransitionManager.beginDelayedTransition(binding.rootView, changeBounds);
|
|
|
|
mConstraintSet.applyTo(binding.rootView);
|
|
}
|
|
|
|
@Override
|
|
public void onBackPressed() {
|
|
if (mIsFilterVisible) {
|
|
showFilter(false);
|
|
binding.txtCurrentTool.setText(R.string.app_name);
|
|
} else if (!mPhotoEditor.isCacheEmpty()) {
|
|
showSaveDialog();
|
|
} else {
|
|
super.onBackPressed();
|
|
}
|
|
}
|
|
}
|