Adding media editor

This commit is contained in:
Thomas 2022-06-05 19:30:31 +02:00
parent 422119d44d
commit 12e352c774
7 changed files with 168 additions and 285 deletions

View file

@ -86,6 +86,9 @@
android:name=".activities.ScheduledActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/scheduled" />
<activity
android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
android:theme="@style/Base.Theme.AppCompat" />
<service
android:name=".services.PostMessageService"

View file

@ -19,8 +19,10 @@ import static app.fedilab.android.ui.drawer.ComposeAdapter.prepareDraft;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
@ -42,6 +44,7 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
@ -58,6 +61,7 @@ import java.util.concurrent.TimeUnit;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Attachment;
import app.fedilab.android.client.entities.api.Context;
import app.fedilab.android.client.entities.api.Mention;
import app.fedilab.android.client.entities.api.ScheduledStatus;
@ -103,6 +107,27 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
private app.fedilab.android.client.entities.api.Account accountMention;
private String statusReplyId;
private final BroadcastReceiver imageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(android.content.Context context, Intent intent) {
String imgpath = intent.getStringExtra("imgpath");
if (imgpath != null) {
int position = 0;
for (Status status : statusList) {
if (status.media_attachments != null && status.media_attachments.size() > 0) {
for (Attachment attachment : status.media_attachments) {
if (attachment.local_path.equalsIgnoreCase(imgpath)) {
composeAdapter.notifyItemChanged(position);
break;
}
}
}
position++;
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -272,6 +297,17 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
}
MastodonHelper.loadPPMastodon(binding.profilePicture, account.mastodon_account);
LocalBroadcastManager.getInstance(this)
.registerReceiver(imageReceiver,
new IntentFilter(Helper.INTENT_SEND_MODIFIED_IMAGE));
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(imageReceiver);
}
@Override

View file

@ -1,34 +1,27 @@
package app.fedilab.android.imageeditor;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static app.fedilab.android.imageeditor.FileSaveHelper.isSdkHigherThan28;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnticipateOvershootInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.exifinterface.media.ExifInterface;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.transition.ChangeBounds;
import androidx.transition.TransitionManager;
@ -40,6 +33,8 @@ import java.io.IOException;
import java.io.InputStream;
import app.fedilab.android.R;
import app.fedilab.android.databinding.ActivityEditImageBinding;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.imageeditor.base.BaseActivity;
import app.fedilab.android.imageeditor.filters.FilterListener;
import app.fedilab.android.imageeditor.filters.FilterViewAdapter;
@ -48,7 +43,6 @@ import app.fedilab.android.imageeditor.tools.ToolType;
import es.dmoral.toasty.Toasty;
import ja.burhanrashid52.photoeditor.OnPhotoEditorListener;
import ja.burhanrashid52.photoeditor.PhotoEditor;
import ja.burhanrashid52.photoeditor.PhotoEditorView;
import ja.burhanrashid52.photoeditor.PhotoFilter;
import ja.burhanrashid52.photoeditor.SaveSettings;
import ja.burhanrashid52.photoeditor.TextStyleBuilder;
@ -60,35 +54,23 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
View.OnClickListener,
PropertiesBSFragment.Properties,
ShapeBSFragment.Properties,
EmojiBSFragment.EmojiListener,
StickerBSFragment.StickerListener, EditingToolsAdapter.OnItemSelected, FilterListener {
EmojiBSFragment.EmojiListener, EditingToolsAdapter.OnItemSelected, FilterListener {
public static final String FILE_PROVIDER_AUTHORITY = "com.burhanrashid52.photoeditor.fileprovider";
public static final String ACTION_NEXTGEN_EDIT = "action_nextgen_edit";
public static final String PINCH_TEXT_SCALABLE_INTENT_KEY = "PINCH_TEXT_SCALABLE";
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;
@Nullable
@VisibleForTesting
Uri mSaveImageUri;
private PhotoEditorView mPhotoEditorView;
private PropertiesBSFragment mPropertiesBSFragment;
private ShapeBSFragment mShapeBSFragment;
private ShapeBuilder mShapeBuilder;
private EmojiBSFragment mEmojiBSFragment;
private StickerBSFragment mStickerBSFragment;
private TextView mTxtCurrentTool;
private Typeface mWonderFont;
private RecyclerView mRvTools, mRvFilters;
private ConstraintLayout mRootView;
private boolean mIsFilterVisible;
private Uri uri;
private boolean exit;
private FileSaveHelper mSaveFileHelper;
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
@ -101,59 +83,47 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
return 0;
}
String path;
private ActivityEditImageBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
makeFullScreen();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_image);
binding = ActivityEditImageBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Bundle b = getIntent().getExtras();
if (getSupportActionBar() != null)
getSupportActionBar().hide();
String path = null;
if (b != null)
path = b.getString("imageUri", null);
if (path == null) {
finish();
}
uri = Uri.parse(path);
uri = Uri.parse("file://" + path);
exit = false;
initViews();
handleIntentImage(mPhotoEditorView.getSource());
mWonderFont = Typeface.createFromAsset(getAssets(), "beyond_wonderland.ttf");
mPropertiesBSFragment = new PropertiesBSFragment();
mEmojiBSFragment = new EmojiBSFragment();
mStickerBSFragment = new StickerBSFragment();
mShapeBSFragment = new ShapeBSFragment();
mStickerBSFragment.setStickerListener(this);
mEmojiBSFragment.setEmojiListener(this);
mPropertiesBSFragment.setPropertiesChangeListener(this);
mShapeBSFragment.setPropertiesChangeListener(this);
LinearLayoutManager llmTools = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRvTools.setLayoutManager(llmTools);
mRvTools.setAdapter(mEditingToolsAdapter);
binding.rvConstraintTools.setLayoutManager(llmTools);
binding.rvConstraintTools.setAdapter(mEditingToolsAdapter);
LinearLayoutManager llmFilters = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRvFilters.setLayoutManager(llmFilters);
mRvFilters.setAdapter(mFilterViewAdapter);
// NOTE(lucianocheng): Used to set integration testing parameters to PhotoEditor
boolean pinchTextScalable = getIntent().getBooleanExtra(PINCH_TEXT_SCALABLE_INTENT_KEY, true);
binding.rvFilterView.setLayoutManager(llmFilters);
binding.rvFilterView.setAdapter(mFilterViewAdapter);
//Typeface mTextRobotoTf = ResourcesCompat.getFont(this, R.font.roboto_medium);
//Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");
Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");
mPhotoEditor = new PhotoEditor.Builder(this, mPhotoEditorView)
.setPinchTextScalable(pinchTextScalable) // set flag to make text scalable when pinch
//.setDefaultTextTypeface(mTextRobotoTf)
mPhotoEditor = new PhotoEditor.Builder(this, binding.photoEditorView)
.setPinchTextScalable(true)
.setDefaultEmojiTypeface(mEmojiTypeFace)
.build(); // build photo editor sdk
@ -163,93 +133,46 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
//Set Image Dynamically
try {
mPhotoEditorView.getSource().setImageURI(uri);
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)) {
assert inputStream != null;
ExifInterface exif = new ExifInterface(inputStream);
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
} catch (Exception e) {
e.printStackTrace();
}
}
Button send = findViewById(R.id.send);
send.setOnClickListener(v -> {
mPhotoEditor.setFilterEffect(PhotoFilter.NONE);
binding.send.setOnClickListener(v -> {
exit = true;
saveImage();
});
}
private void handleIntentImage(ImageView source) {
Intent intent = getIntent();
if (intent != null) {
// NOTE(lucianocheng): Using "yoda conditions" here to guard against
// a null Action in the Intent.
if (Intent.ACTION_EDIT.equals(intent.getAction()) ||
ACTION_NEXTGEN_EDIT.equals(intent.getAction())) {
try {
Uri uri = intent.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
source.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
} else {
String intentType = intent.getType();
if (intentType != null && intentType.startsWith("image/")) {
Uri imageUri = intent.getData();
if (imageUri != null) {
source.setImageURI(imageUri);
}
}
@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() {
ImageView imgUndo;
ImageView imgRedo;
ImageView imgCamera;
ImageView imgGallery;
ImageView imgSave;
ImageView imgClose;
ImageView imgCrop;
mPhotoEditorView = findViewById(R.id.photoEditorView);
mTxtCurrentTool = findViewById(R.id.txtCurrentTool);
mRvTools = findViewById(R.id.rvConstraintTools);
mRvFilters = findViewById(R.id.rvFilterView);
mRootView = findViewById(R.id.rootView);
imgUndo = findViewById(R.id.imgUndo);
imgUndo.setOnClickListener(this);
imgRedo = findViewById(R.id.imgRedo);
imgRedo.setOnClickListener(this);
imgCamera = findViewById(R.id.imgCamera);
imgCamera.setOnClickListener(this);
imgGallery = findViewById(R.id.imgGallery);
imgGallery.setOnClickListener(this);
imgSave = findViewById(R.id.imgSave);
imgSave.setOnClickListener(this);
imgClose = findViewById(R.id.imgClose);
imgClose.setOnClickListener(this);
imgCrop = findViewById(R.id.imgCrop);
imgCrop.setOnClickListener(this);
binding.imgUndo.setOnClickListener(this);
binding.imgRedo.setOnClickListener(this);
binding.imgClose.setOnClickListener(this);
}
@Override
@ -261,7 +184,7 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
styleBuilder.withTextColor(newColorCode);
mPhotoEditor.editText(rootView, inputText, styleBuilder);
mTxtCurrentTool.setText(R.string.label_text);
binding.txtCurrentTool.setText(R.string.label_text);
});
}
@ -285,100 +208,64 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
public void onTouchSourceImage(MotionEvent event) {
}
@SuppressLint("NonConstantResourceId")
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imgUndo:
mPhotoEditor.undo();
break;
case R.id.imgRedo:
mPhotoEditor.redo();
break;
case R.id.imgSave:
saveImage();
break;
case R.id.imgClose:
onBackPressed();
break;
case R.id.imgCrop:
shareImage();
break;
case R.id.imgCamera:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
break;
case R.id.imgGallery:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_REQUEST);
break;
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 shareImage() {
if (mSaveImageUri == null) {
//showSnackbar(getString(R.string.msg_save_image_to_share));
return;
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, buildFileProviderUri(mSaveImageUri));
startActivity(Intent.createChooser(intent, getString(R.string.msg_share_image)));
}
private Uri buildFileProviderUri(@NonNull Uri uri) {
return FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
new File(uri.getPath()));
}
private void saveImage() {
final String fileName = System.currentTimeMillis() + ".png";
final boolean hasStoragePermission =
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED;
if (hasStoragePermission || isSdkHigherThan28()) {
showLoading("Saving...");
mSaveFileHelper.createFile(fileName, (fileCreated, filePath, error, uri) -> {
if (fileCreated) {
SaveSettings saveSettings = new SaveSettings.Builder()
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showLoading(getString(R.string.saving));
File file = new File(path);
try {
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
mPhotoEditor.saveAsFile(filePath, saveSettings, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
mSaveFileHelper.notifyThatFileIsNowPubliclyAvailable(getContentResolver());
hideLoading();
showSnackbar("Image Saved Successfully");
mSaveImageUri = uri;
mPhotoEditorView.getSource().setImageURI(mSaveImageUri);
}
@Override
public void onFailure(@NonNull Exception exception) {
hideLoading();
showSnackbar("Failed to save Image");
}
});
} else {
hideLoading();
showSnackbar(error);
SaveSettings saveSettings = new SaveSettings.Builder()
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
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;
}
});
} else {
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
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);
intentImage.putExtra("imgpath", imagePath);
LocalBroadcastManager.getInstance(EditImageActivity.this).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());
}
}
}
}
@ -406,8 +293,8 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
if (data != null && data.getExtras() != null) {
mPhotoEditor.clearAllViews();
Bitmap photo = (Bitmap) data.getExtras().get("data");
mPhotoEditorView.getSource().setImageBitmap(photo);
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
binding.photoEditorView.getSource().setImageBitmap(photo);
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
}
break;
case PICK_REQUEST:
@ -416,8 +303,8 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
mPhotoEditor.clearAllViews();
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
mPhotoEditorView.getSource().setImageBitmap(bitmap);
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
binding.photoEditorView.getSource().setImageBitmap(bitmap);
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
} catch (IOException e) {
e.printStackTrace();
}
@ -429,8 +316,8 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
if (result != null) {
Uri resultUri = result.getUri();
if (resultUri != null) {
mPhotoEditorView.getSource().setImageURI(resultUri);
mPhotoEditorView.getSource().setRotation(rotationInDegrees);
binding.photoEditorView.getSource().setImageURI(resultUri);
binding.photoEditorView.getSource().setRotation(rotationInDegrees);
if (uri != null && uri.getPath() != null) {
File fdelete = new File(uri.getPath());
if (fdelete.exists()) {
@ -449,19 +336,19 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
@Override
public void onColorChanged(int colorCode) {
mPhotoEditor.setShape(mShapeBuilder.withShapeColor(colorCode));
mTxtCurrentTool.setText(R.string.label_brush);
binding.txtCurrentTool.setText(R.string.label_brush);
}
@Override
public void onOpacityChanged(int opacity) {
mPhotoEditor.setShape(mShapeBuilder.withShapeOpacity(opacity));
mTxtCurrentTool.setText(R.string.label_brush);
binding.txtCurrentTool.setText(R.string.label_brush);
}
@Override
public void onShapeSizeChanged(int shapeSize) {
mPhotoEditor.setShape(mShapeBuilder.withShapeSize(shapeSize));
mTxtCurrentTool.setText(R.string.label_brush);
binding.txtCurrentTool.setText(R.string.label_brush);
}
@Override
@ -472,22 +359,14 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
@Override
public void onEmojiClick(String emojiUnicode) {
mPhotoEditor.addEmoji(emojiUnicode);
mTxtCurrentTool.setText(R.string.label_emoji);
binding.txtCurrentTool.setText(R.string.label_emoji);
}
@Override
public void onStickerClick(Bitmap bitmap) {
mPhotoEditor.addImage(bitmap);
mTxtCurrentTool.setText(R.string.label_sticker);
}
private void showSaveDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.msg_save_image));
builder.setPositiveButton("Save", (dialog, which) -> saveImage());
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
builder.setNeutralButton("Discard", (dialog, which) -> finish());
builder.setPositiveButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builder.setNegativeButton(R.string.discard, (dialog, which) -> finish());
builder.create().show();
}
@ -504,7 +383,7 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
mPhotoEditor.setBrushDrawingMode(true);
mShapeBuilder = new ShapeBuilder();
mPhotoEditor.setShape(mShapeBuilder);
mTxtCurrentTool.setText(R.string.label_shape);
binding.txtCurrentTool.setText(R.string.label_shape);
showBottomSheetDialogFragment(mShapeBSFragment);
break;
case TEXT:
@ -514,28 +393,30 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
styleBuilder.withTextColor(colorCode);
mPhotoEditor.addText(inputText, styleBuilder);
mTxtCurrentTool.setText(R.string.label_text);
binding.txtCurrentTool.setText(R.string.label_text);
});
break;
case ERASER:
mPhotoEditor.brushEraser();
mTxtCurrentTool.setText(R.string.label_eraser_mode);
binding.txtCurrentTool.setText(R.string.label_eraser_mode);
break;
case FILTER:
mTxtCurrentTool.setText(R.string.label_filter);
binding.txtCurrentTool.setText(R.string.label_filter);
showFilter(true);
break;
case EMOJI:
showBottomSheetDialogFragment(mEmojiBSFragment);
break;
case STICKER:
showBottomSheetDialogFragment(mStickerBSFragment);
break;
case BRUSH:
mPhotoEditor.setBrushDrawingMode(true);
mTxtCurrentTool.setText(R.string.label_brush);
binding.txtCurrentTool.setText(R.string.label_brush);
mPropertiesBSFragment.show(getSupportFragmentManager(), mPropertiesBSFragment.getTag());
break;
case CROP:
Log.v(Helper.TAG, "crop! " + uri);
CropImage.activity(uri)
.start(this);
break;
}
}
@ -549,33 +430,33 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
void showFilter(boolean isVisible) {
mIsFilterVisible = isVisible;
mConstraintSet.clone(mRootView);
mConstraintSet.clone(binding.rootView);
if (isVisible) {
mConstraintSet.clear(mRvFilters.getId(), ConstraintSet.START);
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.START,
mConstraintSet.clear(binding.rvFilterView.getId(), ConstraintSet.START);
mConstraintSet.connect(binding.rvFilterView.getId(), ConstraintSet.START,
ConstraintSet.PARENT_ID, ConstraintSet.START);
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.END,
mConstraintSet.connect(binding.rvFilterView.getId(), ConstraintSet.END,
ConstraintSet.PARENT_ID, ConstraintSet.END);
} else {
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.START,
mConstraintSet.connect(binding.rvFilterView.getId(), ConstraintSet.START,
ConstraintSet.PARENT_ID, ConstraintSet.END);
mConstraintSet.clear(mRvFilters.getId(), ConstraintSet.END);
mConstraintSet.clear(binding.rvFilterView.getId(), ConstraintSet.END);
}
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(350);
changeBounds.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
TransitionManager.beginDelayedTransition(mRootView, changeBounds);
TransitionManager.beginDelayedTransition(binding.rootView, changeBounds);
mConstraintSet.applyTo(mRootView);
mConstraintSet.applyTo(binding.rootView);
}
@Override
public void onBackPressed() {
if (mIsFilterVisible) {
showFilter(false);
mTxtCurrentTool.setText(R.string.app_name);
binding.txtCurrentTool.setText(R.string.app_name);
} else if (!mPhotoEditor.isCacheEmpty()) {
showSaveDialog();
} else {

View file

@ -26,12 +26,12 @@ public class EditingToolsAdapter extends RecyclerView.Adapter<EditingToolsAdapte
public EditingToolsAdapter(OnItemSelected onItemSelected) {
mOnItemSelected = onItemSelected;
mToolList.add(new ToolModel("Crop", R.drawable.ic_crop, ToolType.CROP));
mToolList.add(new ToolModel("Shape", R.drawable.ic_oval, ToolType.SHAPE));
mToolList.add(new ToolModel("Text", R.drawable.ic_text, ToolType.TEXT));
mToolList.add(new ToolModel("Eraser", R.drawable.ic_eraser, ToolType.ERASER));
mToolList.add(new ToolModel("Filter", R.drawable.ic_photo_filter, ToolType.FILTER));
mToolList.add(new ToolModel("Emoji", R.drawable.ic_insert_emoticon, ToolType.EMOJI));
mToolList.add(new ToolModel("Sticker", R.drawable.ic_sticker, ToolType.STICKER));
}
@NonNull

View file

@ -12,5 +12,6 @@ public enum ToolType {
ERASER,
FILTER,
EMOJI,
STICKER
STICKER,
CROP
}

View file

@ -65,6 +65,7 @@ import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
@ -439,6 +440,8 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
if ((attachment.type != null && attachment.type.toLowerCase().startsWith("image")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("image"))) {
Glide.with(composeAttachmentItemBinding.preview.getContext())
.load(attachmentPath)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(composeAttachmentItemBinding.preview);
} else if ((attachment.type != null && attachment.type.toLowerCase().startsWith("video")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("video"))) {
composeAttachmentItemBinding.buttonPlay.setVisibility(View.VISIBLE);

View file

@ -23,8 +23,7 @@
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:photo_src="@drawable/blank_image" />
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imgUndo"
@ -46,32 +45,12 @@
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintEnd_toEndOf="parent" />
<ImageView
android:id="@+id/imgGallery"
android:layout_width="@dimen/top_tool_icon_width"
android:layout_height="wrap_content"
android:background="@color/semi_black_transparent"
android:padding="8dp"
android:src="@drawable/ic_gallery"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/imgCamera"
android:layout_width="@dimen/top_tool_icon_width"
android:layout_height="wrap_content"
android:background="@color/semi_black_transparent"
android:padding="8dp"
android:src="@drawable/ic_camera"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintStart_toEndOf="@id/imgGallery" />
<ImageView
android:id="@+id/imgClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_margin="8dp"
android:src="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="parent"
@ -80,7 +59,7 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvConstraintTools"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/tool_bg"
android:orientation="horizontal"
@ -118,26 +97,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<ImageView
android:id="@+id/imgSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:src="@drawable/ic_save"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<ImageView
android:id="@+id/imgCrop"
android:layout_width="@dimen/top_tool_icon_width"
android:layout_height="wrap_content"
android:background="@color/semi_black_transparent"
android:padding="8dp"
android:src="@drawable/ic_crop"
app:layout_constraintBottom_toBottomOf="@+id/photoEditorView"
app:layout_constraintEnd_toStartOf="@+id/imgUndo"
app:layout_constraintStart_toEndOf="@+id/imgCamera" />
<Button
android:id="@+id/send"
@ -150,6 +109,6 @@
android:padding="0dp"
android:text="@string/validate"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imgSave"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>