diff --git a/.documentation/FAQ.md b/.documentation/FAQ.md
new file mode 100644
index 00000000..99e7f16d
--- /dev/null
+++ b/.documentation/FAQ.md
@@ -0,0 +1,84 @@
+# Frequently Asked Questions
+
+## Can't see the crop button. So, can't crop the image.
+Does your app theme has no action bar? If yes, you should add this to your manifest
+```kt
+
+```
+
+## Can I use this library in Java project?
+Yes! Check [Using the library in Java](
+.documentation/java_usage.md)
+
+## Bad class file error : class file has wrong version xx.0, should be yy.0
+It means your Java runtime version is different from your compiler version (javac).
+To simply solve it, just advance your JVM version to 11
+
+- Select "File" -> "Project Structure".
+- Under "Project Settings" select "Project"
+- From there you can select the "Project SDK".
+- But if you don't want to change the Java runtime version, then do the following steps:
+`JAVA_HOME= "your jdk v11 folder path", to make sure jdk is also v11 and use java -version and javac -version again to ensure it`
+
+[more information](https://stackoverflow.com/a/4692743/3117650)
+
+## Why Java 11 is needed since version 3.3.4?
+We update to Java 11 so we could update Gradle.
+And is always good to keep the most updated versions available.
+Those who do not update, keep using old versions of the library, but those who update can get the benefits of the latest versions.
+
+## Downloading the Cropped image to a file
+**Ref:** [[BUG] - Uri Received lacks 'file' scheme](https://github.com/CanHub/Android-Image-Cropper/issues/368)
+
+If you need to use the cropped Image as a file e.g. send it as a file to back-end server
+You need to re-build the Uri as follow
+
+**With Android/jetpack compose**
+```kotlin
+val imageCropLauncher = rememberLauncherForActivityResult(contract = CropImageContract()) { result ->
+ if (result.isSuccessful) {
+ // use the cropped image
+ resultImageUri = result.uriContent
+ imageFilePath = result.getUriFilePath(context = context, uniqueName = true).toString()
+ if (resultImageUri?.scheme?.contains("content") == true) {
+ // replace Scheme to file
+ val builder = Uri.Builder()
+ builder.scheme("file")
+ .appendPath(imageFilePath)
+ val imageUri = builder.build()
+ // Use the imageUri then to send the file
+ }
+ } else {
+ // an error occurred cropping
+ val exception = result.error
+ Log.e(GLOBAL_TAG, "CropImageContract Exception $exception")
+ }
+}
+```
+**Convert the Uri to File**
+```kotlin
+val file: File = imageUri.toFile()
+```
+**With Retrofit/Okhttp3 you can now send it**
+```kotlin
+val response = postApi.createPost(
+ postData = MultipartBody.Part
+ .createFormData(
+ "post_data",
+ gson.toJson(request)
+ ),
+ postImage = MultipartBody.Part
+ .createFormData(
+ name = "post_image",
+ filename = file.name,
+ body = file.asRequestBody()
+ )
+)
+```
+**Note:**
+be sure to test for Errors/Exceptions along the way!
+Tested on Android Studio Chipmunk | 2021.2.1
+Android API 31 Platform
+android_image_cropper_version = "4.2.1"
+
diff --git a/art/activity visual customization.png b/.documentation/art/activity visual customization.png
similarity index 100%
rename from art/activity visual customization.png
rename to .documentation/art/activity visual customization.png
diff --git a/art/async-crop-figure-1.png b/.documentation/art/async-crop-figure-1.png
similarity index 100%
rename from art/async-crop-figure-1.png
rename to .documentation/art/async-crop-figure-1.png
diff --git a/art/async-crop-figure-2.png b/.documentation/art/async-crop-figure-2.png
similarity index 100%
rename from art/async-crop-figure-2.png
rename to .documentation/art/async-crop-figure-2.png
diff --git a/art/canhub_logo_horizontal_transparent.png b/.documentation/art/canhub_logo_horizontal_transparent.png
similarity index 100%
rename from art/canhub_logo_horizontal_transparent.png
rename to .documentation/art/canhub_logo_horizontal_transparent.png
diff --git a/art/crop.jpg b/.documentation/art/crop.jpg
similarity index 100%
rename from art/crop.jpg
rename to .documentation/art/crop.jpg
diff --git a/art/demo.gif b/.documentation/art/demo.gif
similarity index 100%
rename from art/demo.gif
rename to .documentation/art/demo.gif
diff --git a/art/non-straight cropping.png b/.documentation/art/non-straight cropping.png
similarity index 100%
rename from art/non-straight cropping.png
rename to .documentation/art/non-straight cropping.png
diff --git a/art/pick image.gif b/.documentation/art/pick image.gif
similarity index 100%
rename from art/pick image.gif
rename to .documentation/art/pick image.gif
diff --git a/art/read_package.png b/.documentation/art/read_package.png
similarity index 100%
rename from art/read_package.png
rename to .documentation/art/read_package.png
diff --git a/art/visual customization.png b/.documentation/art/visual customization.png
similarity index 100%
rename from art/visual customization.png
rename to .documentation/art/visual customization.png
diff --git a/art/zoom sample small 2.gif b/.documentation/art/zoom sample small 2.gif
similarity index 100%
rename from art/zoom sample small 2.gif
rename to .documentation/art/zoom sample small 2.gif
diff --git a/art/zoom sample small 3.gif b/.documentation/art/zoom sample small 3.gif
similarity index 100%
rename from art/zoom sample small 3.gif
rename to .documentation/art/zoom sample small 3.gif
diff --git a/art/zoom sample small.gif b/.documentation/art/zoom sample small.gif
similarity index 100%
rename from art/zoom sample small.gif
rename to .documentation/art/zoom sample small.gif
diff --git a/art/zoom sample.gif b/.documentation/art/zoom sample.gif
similarity index 100%
rename from art/zoom sample.gif
rename to .documentation/art/zoom sample.gif
diff --git a/.documentation/crop_view.md b/.documentation/crop_view.md
new file mode 100644
index 00000000..9a378c37
--- /dev/null
+++ b/.documentation/crop_view.md
@@ -0,0 +1,27 @@
+## Using CropView
+[Sample code](https://github.com/CanHub/Android-Image-Cropper/tree/main/sample/src/main/java/com/canhub/cropper/sample/SampleUsingImageView.kt)
+
+1. Add `CropImageView` into your activity
+ ```xml
+
+
+ ```
+
+2. Set image to crop
+ ```kotlin
+ cropImageView.setImageUriAsync(uri)
+ // or (prefer using uri for performance and better user experience)
+ cropImageView.setImageBitmap(bitmap)
+ ```
+
+3. Get cropped image
+ ```kotlin
+ // subscribe to async event using cropImageView.setOnCropImageCompleteListener(listener)
+ cropImageView.getCroppedImageAsync()
+ // or
+ val cropped: Bitmap = cropImageView.getCroppedImage()
+ ```
diff --git a/.documentation/custom_activity.md b/.documentation/custom_activity.md
new file mode 100644
index 00000000..47d13cfa
--- /dev/null
+++ b/.documentation/custom_activity.md
@@ -0,0 +1,26 @@
+## Extend to make a custom activity
+[Sample code](https://github.com/CanHub/Android-Image-Cropper/tree/main/sample/src/main/java/com/canhub/cropper/sample/SampleCustomActivity.kt)
+
+If you want to extend the `CropImageActivity` please be aware you will need to setup your `CropImageView`
+
+- Add `CropImageActivity` into your AndroidManifest.xml
+ ```xml
+
+ ```
+- Setup your `CropImageView` after call `super.onCreate(savedInstanceState)`
+ ```kotlin
+override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setCropImageView(binding.cropImageView)
+}
+ ```
+
+### Custom dialog for image source pick
+When calling crop directly the library will prompt a dialog for the user choose between gallery or camera (If you keep both enable).
+We use the Android default AlertDialog for this. If you wanna customised it with your app theme you need to override the method `showImageSourceDialog(..)` when extending the activity _(above)_
+```kotlin
+override fun showImageSourceDialog(openSource: (Source) -> Unit) {
+ super.showImageSourceDialog(openCamera)
+}
+```
\ No newline at end of file
diff --git a/.documentation/features.md b/.documentation/features.md
new file mode 100644
index 00000000..cf300158
--- /dev/null
+++ b/.documentation/features.md
@@ -0,0 +1,76 @@
+# Features
+
+## Optional initial URI
+Crop library can be called with or without image uri
+```kt
+cropImage.launch(
+ options(outputUri) { ... }
+)
+//OR
+cropImage.launch(
+ options { ... }
+)
+```
+
+## Image source
+```kt
+cropImage.launch(
+ options {
+ setImageSource(
+ includeGallery = true,
+ includeCamera = true,
+ )
+ }
+)
+```
+
+### List of options
+```kt
+cropImage.launch(
+ options {
+ setScaleType(CropImageView.ScaleType.FIT_CENTER)
+ setCropShape(CropImageView.CropShape.RECTANGLE)
+ setGuidelines(CropImageView.Guidelines.ON_TOUCH)
+ setAspectRatio(1, 1)
+ setMaxZoom(4)
+ setAutoZoomEnabled(true)
+ setMultiTouchEnabled(true)
+ setCenterMoveEnabled(true)
+ setShowCropOverlay(true)
+ setAllowFlipping(true)
+ setSnapRadius(3f)
+ setTouchRadius(48f)
+ setInitialCropWindowPaddingRatio(0.1f)
+ setBorderLineThickness(3f)
+ setBorderLineColor(Color.argb(170, 255, 255, 255))
+ setBorderCornerThickness(2f)
+ setBorderCornerOffset(5f)
+ setBorderCornerLength(14f)
+ setBorderCornerColor(WHITE)
+ setGuidelinesThickness(1f)
+ setGuidelinesColor(R.color.white)
+ setBackgroundColor(Color.argb(119, 0, 0, 0))
+ setMinCropWindowSize(24, 24)
+ setMinCropResultSize(20, 20)
+ setMaxCropResultSize(99999, 99999)
+ setActivityTitle("")
+ setActivityMenuIconColor(0)
+ setOutputUri(outputUri)
+ setOutputCompressFormat(Bitmap.CompressFormat.JPEG)
+ setOutputCompressQuality(90)
+ setRequestedSize(0, 0)
+ setRequestedSize(0, 0, CropImageView.RequestSizeOptions.RESIZE_INSIDE)
+ setInitialCropWindowRectangle(null)
+ setInitialRotation(0)
+ setAllowCounterRotation(false)
+ setFlipHorizontally(false)
+ setFlipVertically(false)
+ setCropMenuCropButtonTitle(null)
+ setCropMenuCropButtonIcon(0)
+ setAllowRotation(true)
+ setNoOutputImage(false)
+ setFixAspectRatio(false)
+ setIntentChooserPriorityList(listOf("com.miui.gallery", "com.google.android.apps.photos"))
+ }
+)
+```
\ No newline at end of file
diff --git a/.documentation/java_usage.md b/.documentation/java_usage.md
new file mode 100644
index 00000000..3681a30e
--- /dev/null
+++ b/.documentation/java_usage.md
@@ -0,0 +1,44 @@
+- [Java Sample Code](https://github.com/CanHub/Android-Image-Cropper/tree/main/sample/src/main/java/com/canhub/cropper/sample/SampleCropJava.java)
+
+Still stuck? Try This Discussion here to a **Plug and Play** Solution to get you started.
+
+- [🚨 Calling an Activity Directly To Handle this using Java](https://github.com/CanHub/Android-Image-Cropper/discussions/236)
+
+So here are the steps to make the migration work for verison [3.3.6](https://github.com/CanHub/Android-Image-Cropper/releases/tag/3.3.6) or below.
+
+Follow this guide first [🚨 How to migrate Android Image Cropper 🚨](https://github.com/CanHub/Android-Image-Cropper/wiki/%F0%9F%9A%A8-How-to-migrate-Android-Image-Cropper--%F0%9F%9A%A8)
+
+Then follow the following strps to make it work.
+
+Note: You need to use a single kotlin file and also enable kotlin compiler for your project to make it work.
+
+### **Enable Compliler**
+
+goto Tools>Kotlin>Configure kotlin in this project and gradle sync the project
+
+
+
+### **Add Kotlin Code**
+
+Now create a kotlin file _GetUri.kt_
+
+add following code `fun CropImage.ActivityResult?.getUri(): Uri? { return this?.uriContent }`
+
+
+### **Get Result**
+
+then in main `onActivityResult()`
+
+```
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
+ if (resultCode == RESULT_OK) {
+ Uri resultUri = GetUriKt.getUri(CropImage.getActivityResult(data));
+ Log.e(TAG, "onActivityResult: "+resultUri.toString());
+ }
+ }
+ }
+```
+
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..c49b62bb
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+ - package-ecosystem: gradle
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ open-pull-requests-limit: 1
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f5feee05..b39a4466 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [x.x.x] - unreleased
+## [4.3.0] - 10/06/2022
+### Added
+- Added a helper text on top of crop overlay which moves along with it. [#381](https://github.com/CanHub/Android-Image-Cropper/issues/381)
+
+### Fixed
+- The translation of `Camera` and `Gallery` does not exist in some languages.[#358](https://github.com/CanHub/Android-Image-Cropper/issues/358)
+
## [4.2.1] - 04/04/2022
### Added
- Added support for optionally displaying an intent chooser when selecting image source. [#325](https://github.com/CanHub/Android-Image-Cropper/issues/325)
diff --git a/README.md b/README.md
index 35cb20aa..4aadba1c 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,24 @@
-[](https://github.com/canhub)
+[](https://github.com/canhub)
[](https://jitpack.io/#CanHub/Android-Image-Cropper)
-[🚨How to migrate from ArthurHub/Android-Image-Cropper🚨](https://github.com/CanHub/Android-Image-Cropper/wiki/🚨-How-to-migrate-Android-Image-Cropper--🚨)
+☕[Using the library in Java](.documentation/java_usage.md)
-[Java Sample Code](https://github.com/CanHub/Android-Image-Cropper/tree/main/sample/src/main/java/com/canhub/cropper/sample/crop_image_java)
-
-Wanna help the project? Amazing!
-- [Contributing Guide](https://github.com/CanHub/Android-Image-Cropper/blob/main/CONTRIBUTING.md)
+❓[FAQ - frequently asked question](.documentation/FAQ.md)
Android Image Cropper
=======
-**Powerful** (Zoom, Rotation, Multi-Source);
-**Customizable** (Shape, Limits, Style);
-**Optimized** (Async, Sampling, Matrix);
-**Simple** image cropping library for Android.
+- **Powerful** (Zoom, Rotation, Multi-Source);
+- **Customizable** (Shape, Limits, Style);
+- **Optimized** (Async, Sampling, Matrix);
+- **Simple** image cropping library for Android.
-
+[Features List](.documentation/features.md)
-# Add to your project
-
-[See GitHub Wiki for more info.](https://github.com/CanHub/Android-Image-Cropper/wiki)
+
+# Add to your project
### Step 1. Add the JitPack repository to your root build.gradle
-
```gradle
allprojects {
repositories {
@@ -34,7 +29,6 @@ Android Image Cropper
```
### Step 2. Add the dependency
-
```gradle
dependencies {
implementation 'com.github.CanHub:Android-Image-Cropper:${version}'
@@ -42,10 +36,8 @@ Android Image Cropper
```
[Latest Release Version](https://github.com/CanHub/Android-Image-Cropper/releases)
-### Step 3. Add permissions to manifest
-
+### Step 3. Add permissions to manifest
Only need if you run on devices under OS10 (SDK 29)
-
```xml
-
- ```
-
-3. Set image to crop
- ```kotlin
- cropImageView.setImageUriAsync(uri)
- // or (prefer using uri for performance and better user experience)
- cropImageView.setImageBitmap(bitmap)
- ```
-
-4. Get cropped image
- ```kotlin
- // subscribe to async event using cropImageView.setOnCropImageCompleteListener(listener)
- cropImageView.getCroppedImageAsync()
- // or
- val cropped: Bitmap = cropImageView.getCroppedImage()
- ```
-
-## Extend to make a custom activity
-If you want to extend the `CropImageActivity` please be aware you will need to setup your `CropImageView`
-You can check a sample code in this project `com.canhub.cropper.sample.extend_activity.app.SExtendActivity`
-
-- Add `CropImageActivity` into your AndroidManifest.xml
- ```xml
-
- ```
-- Setup your `CropImageView` after call `super.onCreate(savedInstanceState)`
- ```kotlin
-override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setCropImageView(binding.cropImageView)
-}
- ```
-
-### Custom dialog for image source pick
-When calling crop directly the library will prompt a dialog for the user choose between gallery or camera (If you keep both enable).
-We use the Android default AlertDialog for this. If you wanna customised it with your app theme you need to override the method `showImageSourceDialog(..)` when extending the activity _(above)_
-```kotlin
-override fun showImageSourceDialog(openSource: (Source) -> Unit) {
- super.showImageSourceDialog(openCamera)
-}
-```
-
-## Features
-- Built-in `CropImageActivity`.
-- Set cropping image as Bitmap, Resource or Android URI (Gallery, Camera, Dropbox, etc.).
-- Image rotation/flipping during cropping.
-- Auto zoom-in/out to relevant cropping area.
-- Auto rotate bitmap by image Exif data.
-- Set result image min/max limits in pixels.
-- Set initial crop window size/location.
-- Request cropped image resize to specific size.
-- Bitmap memory optimization, OOM handling (should never occur)!
-- API Level 14.
-- More..
-
-## Customizations
-- Cropping window shape: Rectangular, Oval (square/circle by fixing aspect ratio), as well as
- rectangular modes which only allow vertical or horizontal cropping.
-- Cropping window aspect ratio: Free, 1:1, 4:3, 16:9 or Custom.
-- Guidelines appearance: Off / Always On / Show on Touch.
-- Cropping window Border line, border corner and guidelines thickness and color.
-- Cropping background color.
-
-For more information, see the [GitHub Wiki](https://github.com/CanHub/Android-Image-Cropper/wiki).
-
## Posts
- - [Android cropping image from camera or gallery](http://theartofdev.com/2015/02/15/android-cropping-image-from-camera-or-gallery/)
- - [Android Image Cropper async support and custom progress UI](http://theartofdev.com/2016/01/15/android-image-cropper-async-support-and-custom-progress-ui/)
- - [Adding auto-zoom feature to Android-Image-Cropper](https://theartofdev.com/2016/04/25/adding-auto-zoom-feature-to-android-image-cropper/)
+ - [Android cropping image from camera or gallery](https://canato.medium.com/android-cropping-image-from-camera-or-gallery-fbe732800b08)
+
+## Wanna help the project? Amazing!
+- [Contributing Guide](https://github.com/CanHub/Android-Image-Cropper/blob/main/CONTRIBUTING.md)
## License
Forked from [ArthurHub](https://github.com/ArthurHub/Android-Image-Cropper)
diff --git a/cropper/src/main/java/com/canhub/cropper/CropImageContractOptions.kt b/cropper/src/main/java/com/canhub/cropper/CropImageContractOptions.kt
index bdddaa7e..babfa250 100644
--- a/cropper/src/main/java/com/canhub/cropper/CropImageContractOptions.kt
+++ b/cropper/src/main/java/com/canhub/cropper/CropImageContractOptions.kt
@@ -127,6 +127,11 @@ data class CropImageContractOptions @JvmOverloads constructor(
return this
}
+ fun setShowCropLabel(showCropLabel: Boolean): CropImageContractOptions {
+ cropImageOptions.showCropLabel = showCropLabel
+ return this
+ }
+
/**
* if auto-zoom functionality is enabled.
* default: true.
diff --git a/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt b/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt
index 136c9ccc..081142bc 100644
--- a/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt
+++ b/cropper/src/main/java/com/canhub/cropper/CropImageOptions.kt
@@ -83,6 +83,12 @@ open class CropImageOptions : Parcelable {
@JvmField
var showCropOverlay: Boolean
+ /**
+ * If enabled, show a text label on top of crop overlay UI, which gets moved along with the cropper
+ */
+ @JvmField
+ var showCropLabel: Boolean
+
/**
* if to show progress bar when image async loading/cropping is in progress.
* default: true, disable to provide custom progress bar UI.
@@ -311,6 +317,18 @@ open class CropImageOptions : Parcelable {
@JvmField
var intentChooserPriorityList: List?
+ /** The initial text size of cropper label **/
+ @JvmField
+ var cropperLabelTextSize: Float
+
+ /** The default cropper label text color **/
+ @JvmField
+ var cropperLabelTextColor: Int
+
+ /** The default cropper label text **/
+ @JvmField
+ var cropperLabelText: String? = ""
+
/** Init options with defaults. */
constructor() {
val dm = Resources.getSystem().displayMetrics
@@ -373,6 +391,9 @@ open class CropImageOptions : Parcelable {
showIntentChooser = false
intentChooserTitle = null
intentChooserPriorityList = listOf()
+ cropperLabelTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, dm)
+ cropperLabelTextColor = Color.WHITE
+ showCropLabel = false
}
/** Create object from parcel. */
@@ -435,6 +456,10 @@ open class CropImageOptions : Parcelable {
showIntentChooser = parcel.readByte().toInt() != 0
intentChooserTitle = parcel.readString()
intentChooserPriorityList = parcel.createStringArrayList()
+ cropperLabelTextSize = parcel.readFloat()
+ cropperLabelTextColor = parcel.readInt()
+ cropperLabelText = parcel.readString()!!
+ showCropLabel = parcel.readByte().toInt() != 0
}
override fun writeToParcel(dest: Parcel, flags: Int) {
@@ -496,6 +521,10 @@ open class CropImageOptions : Parcelable {
dest.writeByte((if (showIntentChooser) 1 else 0).toByte())
dest.writeString(intentChooserTitle)
dest.writeStringList(intentChooserPriorityList)
+ dest.writeFloat(cropperLabelTextSize)
+ dest.writeInt(cropperLabelTextColor)
+ dest.writeString(cropperLabelText)
+ dest.writeByte((if (showCropLabel) 1 else 0).toByte())
}
override fun describeContents(): Int {
diff --git a/cropper/src/main/java/com/canhub/cropper/CropImageView.kt b/cropper/src/main/java/com/canhub/cropper/CropImageView.kt
index 7033b52c..7cf6c707 100644
--- a/cropper/src/main/java/com/canhub/cropper/CropImageView.kt
+++ b/cropper/src/main/java/com/canhub/cropper/CropImageView.kt
@@ -5,6 +5,7 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.BitmapFactory
+import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Rect
import android.graphics.RectF
@@ -105,6 +106,29 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute
*/
private var mShowCropOverlay = true
+ /** If true, shows a helper text label over crop overlay UI
+ * default: false
+ */
+ private var mShowCropLabel = false
+
+ /**
+ * Helper text label over crop overlay UI
+ * default: empty string
+ */
+ private var mCropTextLabel = ""
+
+ /**
+ * Text size for text label over crop overlay UI
+ * default: 20sp
+ */
+ private var mCropLabelTextSize = 20f
+
+ /**
+ * Text color for text label over crop overlay UI
+ * default: White
+ */
+ private var mCropLabelTextColor = Color.WHITE
+
/**
* if to show progress bar when image async loading/cropping is in progress.
* default: true, disable to provide custom progress bar UI.
@@ -403,6 +427,35 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute
setCropOverlayVisibility()
}
}
+ /**
+ * If enabled, show a text label on top of crop overlay UI, which gets moved along with the cropper
+ */
+ var isShowCropLabel: Boolean
+ get() = mShowCropLabel
+ set(showCropLabel) {
+ if (mShowCropLabel != showCropLabel) {
+ mShowCropLabel = showCropLabel
+ mCropOverlayView?.setCropperTextLabelVisibility(mShowCropLabel)
+ }
+ }
+ var cropLabelText: String
+ get() = mCropTextLabel
+ set(cropLabelText) {
+ mCropTextLabel = cropLabelText
+ mCropOverlayView?.setCropLabelText(cropLabelText)
+ }
+ var cropLabelTextSize: Float
+ get() = mCropLabelTextSize
+ set(textSize) {
+ mCropLabelTextSize = cropLabelTextSize
+ mCropOverlayView?.setCropLabelTextSize(textSize)
+ }
+ var cropLabelTextColor: Int
+ get() = mCropLabelTextColor
+ set(cropLabelTextColor) {
+ mCropLabelTextColor = cropLabelTextColor
+ mCropOverlayView?.setCropLabelTextColor(cropLabelTextColor)
+ }
/** Returns the integer of the imageResource */
/**
* Sets a Drawable as the content of the CropImageView.
@@ -1037,7 +1090,7 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute
bundle.putInt("CROP_MAX_ZOOM", mMaxZoom)
bundle.putBoolean("CROP_FLIP_HORIZONTALLY", mFlipHorizontally)
bundle.putBoolean("CROP_FLIP_VERTICALLY", mFlipVertically)
-
+ bundle.putBoolean("SHOW_CROP_LABEL", mShowCropLabel)
return bundle
}
@@ -1088,6 +1141,8 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute
mMaxZoom = state.getInt("CROP_MAX_ZOOM")
mFlipHorizontally = state.getBoolean("CROP_FLIP_HORIZONTALLY")
mFlipVertically = state.getBoolean("CROP_FLIP_VERTICALLY")
+ mShowCropLabel = state.getBoolean("SHOW_CROP_LABEL")
+ mCropOverlayView.setCropperTextLabelVisibility(mShowCropLabel)
}
super.onRestoreInstanceState(state.getParcelable("instanceState"))
} else {
@@ -1882,6 +1937,21 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute
R.styleable.CropImageView_cropFlipHorizontally,
options.flipVertically
)
+ options.cropperLabelTextSize = ta.getDimension(
+ R.styleable.CropImageView_cropperLabelTextSize,
+ options.cropperLabelTextSize
+ )
+ options.cropperLabelTextColor = ta.getInteger(
+ R.styleable.CropImageView_cropperLabelTextColor,
+ options.cropperLabelTextColor
+ )
+ options.cropperLabelText = ta.getString(
+ R.styleable.CropImageView_cropperLabelText
+ )
+ options.showCropLabel = ta.getBoolean(
+ R.styleable.CropImageView_cropShowLabel,
+ options.showCropLabel
+ )
isSaveBitmapToInstanceState = ta.getBoolean(
R.styleable.CropImageView_cropSaveBitmapToInstanceState,
isSaveBitmapToInstanceState
@@ -1902,6 +1972,8 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute
mScaleType = options.scaleType
mAutoZoomEnabled = options.autoZoomEnabled
mMaxZoom = options.maxZoom
+ mCropLabelTextSize = options.cropperLabelTextSize
+ mShowCropLabel = options.showCropLabel
mShowCropOverlay = options.showCropOverlay
mShowProgressBar = options.showProgressBar
mFlipHorizontally = options.flipHorizontally
diff --git a/cropper/src/main/java/com/canhub/cropper/CropOverlayView.kt b/cropper/src/main/java/com/canhub/cropper/CropOverlayView.kt
index 9579ec7b..237191b8 100644
--- a/cropper/src/main/java/com/canhub/cropper/CropOverlayView.kt
+++ b/cropper/src/main/java/com/canhub/cropper/CropOverlayView.kt
@@ -34,6 +34,16 @@ class CropOverlayView
companion object {
+ /**
+ * Creates the paint object for drawing text label over crop overlay */
+ private fun getTextPaint(options: CropImageOptions): Paint =
+ Paint().apply {
+ strokeWidth = 1f
+ textSize = options.cropperLabelTextSize
+ style = Paint.Style.FILL
+ textAlign = Paint.Align.CENTER
+ this.color = options.cropperLabelTextColor
+ }
/** Creates the Paint object for drawing. */
private fun getNewPaint(color: Int): Paint =
Paint().apply {
@@ -92,6 +102,8 @@ class CropOverlayView
/** The Paint used to darken the surrounding areas outside the crop area. */
private var mBackgroundPaint: Paint? = null
+ private var textLabelPaint: Paint? = null
+
/** Used for oval crop window shape or non-straight rotation drawing. */
private val mPath = Path()
@@ -164,6 +176,14 @@ class CropOverlayView
var cornerShape: CropImageView.CropCornerShape? = null
private set
+ /** To show the text label over crop overlay **/
+ private var isCropLabelEnabled: Boolean = false
+ /** Text to show over text label over crop overlay */
+ private var cropLabelText: String = ""
+ /** Text color to apply over text label over crop overlay */
+ private var cropLabelTextSize: Float = 20f
+ /** Text color to apply over text label over crop overlay */
+ private var cropLabelTextColor = Color.WHITE
/** the initial crop window rectangle to set */
private val mInitialCropWindowRect = Rect()
@@ -253,7 +273,37 @@ class CropOverlayView
invalidate()
}
}
+ /**
+ * Sets the cropper label if it is enabled
+ */
+ fun setCropperTextLabelVisibility(isEnabled: Boolean) {
+ this.isCropLabelEnabled = isEnabled
+ invalidate()
+ }
+
+ /**
+ * Sets the copy text for cropper text
+ */
+ fun setCropLabelText(textLabel: String?) {
+ textLabel?.let {
+ this.cropLabelText = it
+ }
+ }
+ /**
+ * Sets the text size for cropper text
+ */
+ fun setCropLabelTextSize(textSize: Float) {
+ this.cropLabelTextSize = textSize
+ invalidate()
+ }
+ /**
+ * Sets the text color for cropper text
+ */
+ fun setCropLabelTextColor(textColor: Int) {
+ this.cropLabelTextColor = textColor
+ invalidate()
+ }
/**
* Sets the guidelines for the CropOverlayView to be either on, off, or to show when resizing the
* application.
@@ -410,6 +460,10 @@ class CropOverlayView
fun setInitialAttributeValues(options: CropImageOptions) {
mOptions = options
mCropWindowHandler.setInitialAttributeValues(options)
+ setCropLabelTextColor(options.cropperLabelTextColor)
+ setCropLabelTextSize(options.cropperLabelTextSize)
+ setCropLabelText(options.cropperLabelText)
+ setCropperTextLabelVisibility(options.showCropLabel)
setCropCornerRadius(options.cropCornerRadius)
setCropCornerShape(options.cornerShape)
setCropShape(options.cropShape)
@@ -430,6 +484,7 @@ class CropOverlayView
getNewPaintOrNull(options.borderCornerThickness, options.borderCornerColor)
mGuidelinePaint = getNewPaintOrNull(options.guidelinesThickness, options.guidelinesColor)
mBackgroundPaint = getNewPaint(options.backgroundColor)
+ textLabelPaint = getTextPaint(options)
}
/**
@@ -570,10 +625,26 @@ class CropOverlayView
}
// To retain the changes in Paint object when the App goes background this is required
mBorderCornerPaint = getNewPaintOrNull(mOptions?.borderCornerThickness ?: 0.0f, mOptions?.borderCornerColor ?: Color.WHITE)
+ drawCropLabelText(canvas)
drawBorders(canvas)
drawCorners(canvas)
}
+ /** Draws a text label (which can acts an helper text) on top of crop overlay **/
+ private fun drawCropLabelText(canvas: Canvas) {
+ if (isCropLabelEnabled) {
+ val rect = mCropWindowHandler.getRect()
+ var xCoordinate = (rect.left + rect.right) / 2
+ var yCoordinate = rect.top - 50
+ textLabelPaint?.apply {
+ textSize = cropLabelTextSize
+ color = cropLabelTextColor
+ }
+ canvas.drawText(cropLabelText, xCoordinate, yCoordinate, textLabelPaint!!)
+ canvas.save()
+ }
+ }
+
/** Draw shadow background over the image not including the crop area. */
private fun drawBackground(canvas: Canvas) {
val rect = mCropWindowHandler.getRect()
diff --git a/cropper/src/main/res/values-ar/strings.xml b/cropper/src/main/res/values-ar/strings.xml
index 5f5fe5a4..94e5c568 100644
--- a/cropper/src/main/res/values-ar/strings.xml
+++ b/cropper/src/main/res/values-ar/strings.xml
@@ -8,9 +8,9 @@
اقلب
اقلب أفقيًا
اقلب رأسيًا
-
اختر مصدرًا
-
+ الة تصوير
+ صالة عرض
إلغاء؛ الأذونات المطلوبة غير ممنوحة
diff --git a/cropper/src/main/res/values-de/strings.xml b/cropper/src/main/res/values-de/strings.xml
index a4eacd34..d24e6599 100644
--- a/cropper/src/main/res/values-de/strings.xml
+++ b/cropper/src/main/res/values-de/strings.xml
@@ -8,9 +8,9 @@
spiegeln
horizontal spiegeln
vertikal spiegeln
-
Quelle wählen
-
+ Kamera
+ Galerie
Vorgang wird abgebrochen, benötigte Berechtigungen wurden nicht erteilt.
diff --git a/cropper/src/main/res/values-es-rGT/strings.xml b/cropper/src/main/res/values-es-rGT/strings.xml
index e299d8d5..2b639955 100644
--- a/cropper/src/main/res/values-es-rGT/strings.xml
+++ b/cropper/src/main/res/values-es-rGT/strings.xml
@@ -8,5 +8,7 @@
Voltear horizontalmente
Voltear verticalmente
Seleccionar fuente
+ Cámara
+ Galería
Cancelando, los permisos requeridos no se otorgaron
\ No newline at end of file
diff --git a/cropper/src/main/res/values-es/strings.xml b/cropper/src/main/res/values-es/strings.xml
index a8bc1e7f..f7446cc6 100644
--- a/cropper/src/main/res/values-es/strings.xml
+++ b/cropper/src/main/res/values-es/strings.xml
@@ -5,8 +5,10 @@
Rotar a la derecha
Cortar
Dar la vuelta
- Voltear horizontalmente
- Voltear verticalmente
+ Girar horizontalmente
+ Girar verticalmente
Seleccionar fuente
+ Cámara
+ Galería
Cancelando, los permisos requeridos no han sido otorgados
\ No newline at end of file
diff --git a/cropper/src/main/res/values-fr/strings.xml b/cropper/src/main/res/values-fr/strings.xml
index e6168923..c3f50bf2 100644
--- a/cropper/src/main/res/values-fr/strings.xml
+++ b/cropper/src/main/res/values-fr/strings.xml
@@ -8,5 +8,7 @@
Retourner horizontalement
Retourner verticalement
Sélectionner la source
+ Appareil photo
+ Galerie
Annulation, il manque des permissions requises
diff --git a/cropper/src/main/res/values-it/strings.xml b/cropper/src/main/res/values-it/strings.xml
index 77545864..01602e12 100644
--- a/cropper/src/main/res/values-it/strings.xml
+++ b/cropper/src/main/res/values-it/strings.xml
@@ -10,7 +10,8 @@
Capovolgi verticalmente
Seleziona origine
-
+ Fotocamera
+ Galleria
Annullamento in corso, autorizzazione richieste non concesse
diff --git a/cropper/src/main/res/values-nl/strings.xml b/cropper/src/main/res/values-nl/strings.xml
index b69dda00..cc8b5910 100644
--- a/cropper/src/main/res/values-nl/strings.xml
+++ b/cropper/src/main/res/values-nl/strings.xml
@@ -8,9 +8,9 @@
Spiegelen
Horizontaal spiegelen
Verticaal spiegelen
-
Bron selecteren
-
+ Camera
+ Galerij
Wordt geannuleerd, vereiste machtigingen zijn niet toegekend
diff --git a/cropper/src/main/res/values/attrs.xml b/cropper/src/main/res/values/attrs.xml
index 82318aa8..0db22609 100644
--- a/cropper/src/main/res/values/attrs.xml
+++ b/cropper/src/main/res/values/attrs.xml
@@ -54,6 +54,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index 110804c6..55cb9a21 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -8,7 +8,7 @@
android:label="@string/app_name"
android:theme="@style/Theme.Sample">
@@ -17,10 +17,10 @@
-
+
diff --git a/sample/src/main/java/com/canhub/cropper/sample/SMainActivity.kt b/sample/src/main/java/com/canhub/cropper/sample/MainActivity.kt
similarity index 52%
rename from sample/src/main/java/com/canhub/cropper/sample/SMainActivity.kt
rename to sample/src/main/java/com/canhub/cropper/sample/MainActivity.kt
index 846f3c87..6382ccc3 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/SMainActivity.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/MainActivity.kt
@@ -3,13 +3,9 @@ package com.canhub.cropper.sample
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
-import com.canhub.cropper.sample.crop_image.app.SCropImageFragment
-import com.canhub.cropper.sample.crop_image_java.app.SCropImageFragmentJava
-import com.canhub.cropper.sample.crop_image_view.app.SCropImageViewFragment
-import com.canhub.cropper.sample.extend_activity.app.SExtendActivity
import com.example.croppersample.databinding.ActivityMainBinding
-internal class SMainActivity : AppCompatActivity() {
+internal class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
@@ -19,21 +15,10 @@ internal class SMainActivity : AppCompatActivity() {
setContentView(binding.root)
- binding.sampleCropImageView.setOnClickListener {
- SCropImageViewFragment.newInstance().show()
- }
-
- binding.sampleCustomActivity.setOnClickListener {
- SExtendActivity.start(this)
- }
-
- binding.sampleCropImage.setOnClickListener {
- SCropImageFragment.newInstance().show()
- }
-
- binding.sampleCropImageJava.setOnClickListener {
- SCropImageFragmentJava.newInstance().show()
- }
+ binding.sampleCropImageView.setOnClickListener { SampleUsingImageView.newInstance().show() }
+ binding.sampleCustomActivity.setOnClickListener { SampleCustomActivity.start(this) }
+ binding.sampleCropImage.setOnClickListener { SampleCrop.newInstance().show() }
+ binding.sampleCropImageJava.setOnClickListener { SampleCropJava.newInstance().show() }
}
private fun Fragment.show() {
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image/app/SCropImageFragment.kt b/sample/src/main/java/com/canhub/cropper/sample/SampleCrop.kt
similarity index 86%
rename from sample/src/main/java/com/canhub/cropper/sample/crop_image/app/SCropImageFragment.kt
rename to sample/src/main/java/com/canhub/cropper/sample/SampleCrop.kt
index 0b9072cc..d2b90c6f 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image/app/SCropImageFragment.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/SampleCrop.kt
@@ -1,4 +1,4 @@
-package com.canhub.cropper.sample.crop_image.app
+package com.canhub.cropper.sample
import android.graphics.Bitmap
import android.graphics.Color
@@ -14,12 +14,10 @@ import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
+import com.canhub.cropper.CropImage
import com.canhub.cropper.CropImageContract
import com.canhub.cropper.CropImageView
import com.canhub.cropper.options
-import com.canhub.cropper.sample.SCropResultActivity
-import com.canhub.cropper.sample.crop_image.domain.SCropImageContract
-import com.canhub.cropper.sample.crop_image.presenter.SCropImagePresenter
import com.example.croppersample.R
import com.example.croppersample.databinding.FragmentCameraBinding
import java.io.File
@@ -27,11 +25,11 @@ import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
-internal class SCropImageFragment : Fragment(), SCropImageContract.View {
+internal class SampleCrop : Fragment() {
companion object {
- fun newInstance() = SCropImageFragment()
+ fun newInstance() = SampleCrop()
const val DATE_FORMAT = "yyyyMMdd_HHmmss"
const val FILE_NAMING_PREFIX = "JPEG_"
@@ -41,16 +39,27 @@ internal class SCropImageFragment : Fragment(), SCropImageContract.View {
}
private lateinit var binding: FragmentCameraBinding
- private val presenter: SCropImageContract.Presenter = SCropImagePresenter()
private var outputUri: Uri? = null
private val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) {
- presenter.onTakePictureResult(it)
+ if (it) startCameraWithUri() else showErrorMessage("taking picture failed")
}
- private val cropImage = registerForActivityResult(CropImageContract()) {
- presenter.onCropImageResult(it)
+ private val cropImage = registerForActivityResult(CropImageContract()) { result ->
+ when {
+ result.isSuccessful -> {
+ Log.v("Bitmap", result.bitmap.toString())
+ Log.v("File Path", context?.let { result.getUriFilePath(it) }.toString())
+ handleCropImageResult(result.uriContent.toString())
+ }
+ result is CropImage.CancelledResult -> {
+ showErrorMessage("cropping image was cancelled by the user")
+ }
+ else -> {
+ showErrorMessage("cropping image failed")
+ }
+ }
}
private val customCropImage = registerForActivityResult(CropImageContract()) {
- presenter.onCustomCropImageResult(outputUri)
+ handleCropImageResult(it.uriContent.toString())
}
override fun onCreateView(
@@ -64,39 +73,23 @@ internal class SCropImageFragment : Fragment(), SCropImageContract.View {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- presenter.bind(this)
- binding.takePictureBeforeCallLibraryWithUri.setOnClickListener { startTakePicture() }
+ binding.takePictureBeforeCallLibraryWithUri.setOnClickListener {
+ setupOutputUri()
+ takePicture.launch(outputUri)
+ }
binding.callLibraryWithoutUri.setOnClickListener {
- startCameraWithoutUri(
- includeCamera = true,
- includeGallery = true,
- )
+ startCameraWithoutUri(includeCamera = true, includeGallery = true)
}
binding.callLibraryWithoutUriCameraOnly.setOnClickListener {
- startCameraWithoutUri(
- includeCamera = true,
- includeGallery = false,
- )
+ startCameraWithoutUri(includeCamera = true, includeGallery = false)
}
binding.callLibraryWithoutUriGalleryOnly.setOnClickListener {
- startCameraWithoutUri(
- includeCamera = false,
- includeGallery = true,
- )
+ startCameraWithoutUri(includeCamera = false, includeGallery = true)
}
-
- presenter.onCreate(activity, context)
- }
-
- override fun onDestroyView() {
- presenter.unbind()
- super.onDestroyView()
}
private fun startCameraWithoutUri(includeCamera: Boolean, includeGallery: Boolean) {
- setupOutputUri()
-
customCropImage.launch(
options {
setImageSource(
@@ -131,7 +124,6 @@ internal class SCropImageFragment : Fragment(), SCropImageContract.View {
setMaxCropResultSize(99999, 99999)
setActivityTitle("")
setActivityMenuIconColor(0)
- setOutputUri(outputUri)
setOutputCompressFormat(Bitmap.CompressFormat.JPEG)
setOutputCompressQuality(90)
setRequestedSize(0, 0)
@@ -146,7 +138,6 @@ internal class SCropImageFragment : Fragment(), SCropImageContract.View {
setAllowRotation(true)
setNoOutputImage(false)
setFixAspectRatio(false)
-
// Odd Settings
// setScaleType(CropImageView.ScaleType.CENTER)
// setCropShape(CropImageView.CropShape.OVAL)
@@ -202,7 +193,7 @@ internal class SCropImageFragment : Fragment(), SCropImageContract.View {
)
}
- override fun startCameraWithUri() {
+ private fun startCameraWithUri() {
cropImage.launch(
options(outputUri) {
setScaleType(CropImageView.ScaleType.FIT_CENTER)
@@ -251,18 +242,13 @@ internal class SCropImageFragment : Fragment(), SCropImageContract.View {
)
}
- override fun showErrorMessage(message: String) {
+ private fun showErrorMessage(message: String) {
Log.e("Camera Error:", message)
Toast.makeText(activity, "Crop failed: $message", Toast.LENGTH_SHORT).show()
}
- private fun startTakePicture() {
- setupOutputUri()
- takePicture.launch(outputUri)
- }
-
- override fun handleCropImageResult(uri: String) {
- SCropResultActivity.start(this, null, Uri.parse(uri), null)
+ private fun handleCropImageResult(uri: String) {
+ SampleResultScreen.start(this, null, Uri.parse(uri.replace("file:", "")), null)
}
private fun setupOutputUri() {
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/app/SCropImageFragmentJava.java b/sample/src/main/java/com/canhub/cropper/sample/SampleCropJava.java
similarity index 87%
rename from sample/src/main/java/com/canhub/cropper/sample/crop_image_java/app/SCropImageFragmentJava.java
rename to sample/src/main/java/com/canhub/cropper/sample/SampleCropJava.java
index 6af40a50..32a13068 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/app/SCropImageFragmentJava.java
+++ b/sample/src/main/java/com/canhub/cropper/sample/SampleCropJava.java
@@ -1,4 +1,4 @@
-package com.canhub.cropper.sample.crop_image_java.app;
+package com.canhub.cropper.sample;
import static android.graphics.Color.RED;
import static android.graphics.Color.WHITE;
@@ -14,32 +14,27 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
-
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
-
+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.canhub.cropper.sample.SCropResultActivity;
-import com.canhub.cropper.sample.crop_image_java.domain.SCropImageContractJava;
-import com.canhub.cropper.sample.crop_image_java.presenter.SCropImagePresenterJava;
import com.example.croppersample.R;
import com.example.croppersample.databinding.FragmentCameraBinding;
-
import org.jetbrains.annotations.NotNull;
-
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Locale;
+import java.util.Objects;
-public class SCropImageFragmentJava extends Fragment implements SCropImageContractJava.View {
+public class SampleCropJava extends Fragment {
static final String DATE_FORMAT = "yyyyMMdd_HHmmss";
static final String FILE_NAMING_PREFIX = "JPEG_";
@@ -48,18 +43,17 @@ public class SCropImageFragmentJava extends Fragment implements SCropImageContra
static final String AUTHORITY_SUFFIX = ".cropper.fileprovider";
private FragmentCameraBinding binding;
- private final SCropImageContractJava.Presenter presenter = new SCropImagePresenterJava();
private Uri outputUri;
private final ActivityResultLauncher takePicture =
- registerForActivityResult(new ActivityResultContracts.TakePicture(), presenter::onTakePictureResult);
+ registerForActivityResult(new ActivityResultContracts.TakePicture(), this::onTakePictureResult);
private final ActivityResultLauncher cropImage =
- registerForActivityResult(new CropImageContract(), presenter::onCropImageResult);
+ registerForActivityResult(new CropImageContract(), this::onCropImageResult);
- public static SCropImageFragmentJava newInstance() {
- return new SCropImageFragmentJava();
+ public static SampleCropJava newInstance() {
+ return new SampleCropJava();
}
@Nullable
@@ -73,17 +67,13 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- presenter.bind(this);
binding.takePictureBeforeCallLibraryWithUri.setOnClickListener(v -> startTakePicture());
binding.callLibraryWithoutUri.setOnClickListener(v -> startCameraWithoutUri());
-
- presenter.onCreate(getActivity(), getContext());
}
@Override
public void onDestroyView() {
- presenter.unbind();
super.onDestroyView();
}
@@ -135,7 +125,6 @@ private void startCameraWithoutUri() {
cropImage.launch(options);
}
- @Override
public void startCameraWithUri() {
CropImageContractOptions options = new CropImageContractOptions(outputUri, new CropImageOptions())
.setScaleType(CropImageView.ScaleType.FIT_CENTER)
@@ -183,7 +172,6 @@ public void startCameraWithUri() {
cropImage.launch(options);
}
- @Override
public void showErrorMessage(@NotNull String message) {
Log.e("Camera Error:", message);
Toast.makeText(getActivity(), "Crop failed: " + message, Toast.LENGTH_SHORT).show();
@@ -200,9 +188,8 @@ private void startTakePicture() {
}
}
- @Override
public void handleCropImageResult(@NotNull String uri) {
- SCropResultActivity.Companion.start(this, null, Uri.parse(uri), null);
+ SampleResultScreen.Companion.start(this, null, Uri.parse(uri), null);
}
private File createImageFile() throws IOException {
@@ -214,4 +201,21 @@ private File createImageFile() throws IOException {
storageDir
);
}
+
+ public void onCropImageResult(@NonNull CropImageView.CropResult result) {
+ if (result.isSuccessful()) {
+ handleCropImageResult(Objects.requireNonNull(result.getUriContent())
+ .toString()
+ .replace("file:", ""));
+ } else if (result.equals(CropImage.CancelledResult.INSTANCE)) {
+ showErrorMessage("cropping image was cancelled by the user");
+ } else {
+ showErrorMessage("cropping image failed");
+ }
+ }
+
+ public void onTakePictureResult(boolean success) {
+ if (success) { startCameraWithUri(); }
+ else { showErrorMessage("taking picture failed"); }
+ }
}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/extend_activity/app/SExtendActivity.kt b/sample/src/main/java/com/canhub/cropper/sample/SampleCustomActivity.kt
similarity index 63%
rename from sample/src/main/java/com/canhub/cropper/sample/extend_activity/app/SExtendActivity.kt
rename to sample/src/main/java/com/canhub/cropper/sample/SampleCustomActivity.kt
index 442633b4..d1b6a290 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/extend_activity/app/SExtendActivity.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/SampleCustomActivity.kt
@@ -1,4 +1,4 @@
-package com.canhub.cropper.sample.extend_activity.app
+package com.canhub.cropper.sample
import android.app.Activity
import android.content.Intent
@@ -10,41 +10,33 @@ import android.view.View
import androidx.core.app.ActivityCompat
import com.canhub.cropper.CropImage
import com.canhub.cropper.CropImageActivity
-import com.canhub.cropper.sample.extend_activity.domain.SExtendContract
-import com.canhub.cropper.sample.extend_activity.presenter.SExtendPresenter
import com.example.croppersample.R
import com.example.croppersample.databinding.ExtendedActivityBinding
-internal class SExtendActivity : CropImageActivity(), SExtendContract.View {
+internal class SampleCustomActivity : CropImageActivity() {
companion object {
fun start(activity: Activity) {
ActivityCompat.startActivity(
activity,
- Intent(activity, SExtendActivity::class.java),
+ Intent(activity, SampleCustomActivity::class.java),
null
)
}
}
private lateinit var binding: ExtendedActivityBinding
- private val presenter: SExtendContract.Presenter = SExtendPresenter()
+ private var counter = 0
override fun onCreate(savedInstanceState: Bundle?) {
binding = ExtendedActivityBinding.inflate(layoutInflater)
super.onCreate(savedInstanceState)
- presenter.bindView(this)
+ updateRotationCounter(counter.toString())
- binding.saveBtn.setOnClickListener {
- cropImage() // CropImageActivity.cropImage()
- }
- binding.backBtn.setOnClickListener {
- onBackPressed() // CropImageActivity.onBackPressed()
- }
- binding.rotateText.setOnClickListener {
- presenter.onRotateClick()
- }
+ binding.saveBtn.setOnClickListener { cropImage() } // CropImageActivity.cropImage()
+ binding.backBtn.setOnClickListener { onBackPressed() } // CropImageActivity.onBackPressed()
+ binding.rotateText.setOnClickListener { onRotateClick() }
setCropImageView(binding.cropImageView)
}
@@ -59,25 +51,14 @@ internal class SExtendActivity : CropImageActivity(), SExtendContract.View {
super.setContentView(binding.root)
}
- override fun onDestroy() {
- presenter.unbindView()
- super.onDestroy()
- }
-
- override fun rotate(counter: Int) {
- binding.cropImageView.rotateImage(counter)
- }
-
- override fun updateRotationCounter(counter: String) {
+ private fun updateRotationCounter(counter: String) {
binding.rotateText.text = getString(R.string.rotation_value, counter)
}
override fun onPickImageResult(resultUri: Uri?) {
super.onPickImageResult(resultUri)
- if (resultUri != null) {
- binding.cropImageView.setImageUriAsync(resultUri)
- }
+ if (resultUri != null) binding.cropImageView.setImageUriAsync(resultUri)
}
// Override this to add more information into the intent
@@ -88,14 +69,14 @@ internal class SExtendActivity : CropImageActivity(), SExtendContract.View {
override fun setResult(uri: Uri?, error: Exception?, sampleSize: Int) {
val result = CropImage.ActivityResult(
- binding.cropImageView.imageUri,
- uri,
- error,
- binding.cropImageView.cropPoints,
- binding.cropImageView.cropRect,
- binding.cropImageView.rotatedDegrees,
- binding.cropImageView.wholeImageRect,
- sampleSize
+ originalUri = binding.cropImageView.imageUri,
+ uriContent = uri,
+ error = error,
+ cropPoints = binding.cropImageView.cropPoints,
+ cropRect = binding.cropImageView.cropRect,
+ rotation = binding.cropImageView.rotatedDegrees,
+ wholeImageRect = binding.cropImageView.wholeImageRect,
+ sampleSize = sampleSize
)
Log.v("File Path", result.getUriFilePath(this).toString())
@@ -114,4 +95,11 @@ internal class SExtendActivity : CropImageActivity(), SExtendContract.View {
)
super.updateMenuItemIconColor(menu, itemId, color)
}
+
+ private fun onRotateClick() {
+ counter += 90
+ binding.cropImageView.rotateImage(90)
+ if (counter == 360) counter = 0
+ updateRotationCounter(counter.toString())
+ }
}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/SCropResultActivity.kt b/sample/src/main/java/com/canhub/cropper/sample/SampleResultScreen.kt
similarity index 94%
rename from sample/src/main/java/com/canhub/cropper/sample/SCropResultActivity.kt
rename to sample/src/main/java/com/canhub/cropper/sample/SampleResultScreen.kt
index 6383ab1a..ef60b3c1 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/SCropResultActivity.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/SampleResultScreen.kt
@@ -11,11 +11,11 @@ import androidx.fragment.app.Fragment
import com.example.croppersample.R
import com.example.croppersample.databinding.ActivityCropResultBinding
-class SCropResultActivity : Activity() {
+class SampleResultScreen : Activity() {
companion object {
fun start(fragment: Fragment, imageBitmap: Bitmap?, uri: Uri?, sampleSize: Int?) {
- val intent = Intent(fragment.context, SCropResultActivity::class.java)
+ val intent = Intent(fragment.context, SampleResultScreen::class.java)
.putExtra(SAMPLE_SIZE, sampleSize)
.putExtra(URI, uri)
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/SCropImageViewFragment.kt b/sample/src/main/java/com/canhub/cropper/sample/SampleUsingImageView.kt
similarity index 81%
rename from sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/SCropImageViewFragment.kt
rename to sample/src/main/java/com/canhub/cropper/sample/SampleUsingImageView.kt
index a29e617c..b563aade 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/app/SCropImageViewFragment.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/SampleUsingImageView.kt
@@ -1,4 +1,4 @@
-package com.canhub.cropper.sample.crop_image_view.app
+package com.canhub.cropper.sample
import android.graphics.Rect
import android.net.Uri
@@ -18,29 +18,24 @@ import com.canhub.cropper.CropImageView
import com.canhub.cropper.CropImageView.CropResult
import com.canhub.cropper.CropImageView.OnCropImageCompleteListener
import com.canhub.cropper.CropImageView.OnSetImageUriCompleteListener
-import com.canhub.cropper.sample.SCropResultActivity
-import com.canhub.cropper.sample.crop_image_view.domain.SCropImageViewContract
-import com.canhub.cropper.sample.crop_image_view.presenter.SCropImageViewPresenter
-import com.canhub.cropper.sample.options_dialog.app.SOptionsDialogBottomSheet
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsDomain
+import com.canhub.cropper.sample.options_dialog.SampleOptionsBottomSheet
+import com.canhub.cropper.sample.options_dialog.SampleOptionsEntity
import com.example.croppersample.R
import com.example.croppersample.databinding.FragmentCropImageViewBinding
-internal class SCropImageViewFragment :
+internal class SampleUsingImageView :
Fragment(),
- SCropImageViewContract.View,
- SOptionsDialogBottomSheet.Listener,
+ SampleOptionsBottomSheet.Listener,
OnSetImageUriCompleteListener,
OnCropImageCompleteListener {
companion object {
- fun newInstance() = SCropImageViewFragment()
+ fun newInstance() = SampleUsingImageView()
}
private lateinit var binding: FragmentCropImageViewBinding
- private val presenter = SCropImageViewPresenter()
- private var options: SOptionsDomain? = null
+ private var options: SampleOptionsEntity? = null
private val openPicker =
registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
binding.cropImageView.setImageUriAsync(uri)
@@ -59,8 +54,7 @@ internal class SCropImageViewFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- presenter.bind(this)
- presenter.onViewCreated()
+ setOptions()
binding.cropImageView.let {
it.setOnSetImageUriCompleteListener(this)
@@ -69,7 +63,7 @@ internal class SCropImageViewFragment :
}
binding.settings.setOnClickListener {
- SOptionsDialogBottomSheet.show(childFragmentManager, options, this)
+ SampleOptionsBottomSheet.show(childFragmentManager, options, this)
}
binding.searchImage.setOnClickListener {
@@ -91,7 +85,7 @@ internal class SCropImageViewFragment :
}
}
- override fun onOptionsApplySelected(options: SOptionsDomain) {
+ override fun onOptionsApplySelected(options: SampleOptionsEntity) {
this.options = options
binding.cropImageView.apply {
@@ -112,6 +106,7 @@ internal class SCropImageViewFragment :
maxZoom = options.maxZoomLvl
isFlippedHorizontally = options.flipHorizontal
isFlippedVertically = options.flipVertically
+ isShowCropLabel = options.showCropLabel
}
if (options.scaleType == CropImageView.ScaleType.CENTER_INSIDE)
@@ -170,7 +165,7 @@ internal class SCropImageViewFragment :
result.bitmap?.let { CropImage.toOvalBitmap(it) }
else result.bitmap
context?.let { Log.v("File Path", result.getUriFilePath(it).toString()) }
- SCropResultActivity.start(this, imageBitmap, result.uriContent, result.sampleSize)
+ SampleResultScreen.start(this, imageBitmap, result.uriContent, result.sampleSize)
} else {
Log.e("AIC", "Failed to crop image", result?.error)
Toast
@@ -179,8 +174,25 @@ internal class SCropImageViewFragment :
}
}
- override fun setOptions(options: SOptionsDomain) {
+ private fun setOptions() {
binding.cropImageView.cropRect = Rect(100, 300, 500, 1200)
- onOptionsApplySelected(options)
+ onOptionsApplySelected(defaultOptions)
}
+
+ private val defaultOptions: SampleOptionsEntity = SampleOptionsEntity(
+ scaleType = CropImageView.ScaleType.FIT_CENTER,
+ cropShape = CropImageView.CropShape.RECTANGLE,
+ cornerShape = CropImageView.CropCornerShape.RECTANGLE,
+ guidelines = CropImageView.Guidelines.ON,
+ ratio = Pair(1, 1),
+ autoZoom = true,
+ maxZoomLvl = 2,
+ multiTouch = true,
+ centerMove = true,
+ showCropOverlay = true,
+ showProgressBar = true,
+ flipHorizontal = false,
+ flipVertically = false,
+ showCropLabel = false
+ )
}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image/domain/SCropImageContract.kt b/sample/src/main/java/com/canhub/cropper/sample/crop_image/domain/SCropImageContract.kt
deleted file mode 100644
index 29f1404e..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image/domain/SCropImageContract.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.canhub.cropper.sample.crop_image.domain
-
-import android.content.Context
-import android.net.Uri
-import androidx.fragment.app.FragmentActivity
-import com.canhub.cropper.CropImageView
-
-internal interface SCropImageContract {
-
- interface View {
- fun showErrorMessage(message: String)
- fun handleCropImageResult(uri: String)
- fun startCameraWithUri()
- }
-
- interface Presenter {
- fun bind(view: View)
- fun unbind()
- fun onCreate(activity: FragmentActivity?, context: Context?)
- fun onCropImageResult(result: CropImageView.CropResult)
- fun onCustomCropImageResult(customUri: Uri?)
- fun onTakePictureResult(success: Boolean)
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image/presenter/SCropImagePresenter.kt b/sample/src/main/java/com/canhub/cropper/sample/crop_image/presenter/SCropImagePresenter.kt
deleted file mode 100644
index c783a3e7..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image/presenter/SCropImagePresenter.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.canhub.cropper.sample.crop_image.presenter
-
-import android.Manifest
-import android.app.Activity
-import android.content.Context
-import android.content.pm.PackageManager
-import android.net.Uri
-import android.util.Log
-import androidx.core.app.ActivityCompat
-import androidx.fragment.app.FragmentActivity
-import com.canhub.cropper.CropImage
-import com.canhub.cropper.CropImageView
-import com.canhub.cropper.sample.crop_image.domain.SCropImageContract
-
-internal class SCropImagePresenter : SCropImageContract.Presenter {
-
- private var view: SCropImageContract.View? = null
- private var request = false
- private var hasSystemFeature = false
- private var context: Context? = null
-
- override fun bind(view: SCropImageContract.View) {
- this.view = view
- }
-
- override fun unbind() {
- view = null
- }
-
- override fun onCreate(activity: FragmentActivity?, context: Context?) {
- if (activity == null || context == null) {
- view?.showErrorMessage("onCreate activity and/or context are null")
- return
- }
- this.context = context
-
- request = ActivityCompat.shouldShowRequestPermissionRationale(
- activity as Activity,
- Manifest.permission.CAMERA
- )
- hasSystemFeature = context.packageManager
- ?.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) ?: false
- }
-
- override fun onCropImageResult(result: CropImageView.CropResult) {
- when {
- result.isSuccessful -> {
- Log.v("Bitmap", result.bitmap.toString())
- Log.v("File Path", context?.let { result.getUriFilePath(it) }.toString())
- view?.handleCropImageResult(result.uriContent.toString().replace("file:", ""))
- }
- result is CropImage.CancelledResult -> {
- view?.showErrorMessage("cropping image was cancelled by the user")
- }
- else -> {
- view?.showErrorMessage("cropping image failed")
- }
- }
- }
-
- override fun onCustomCropImageResult(customUri: Uri?) {
- view?.handleCropImageResult(customUri.toString().replace("file:", ""))
- }
-
- override fun onTakePictureResult(success: Boolean) {
- if (success) view?.startCameraWithUri()
- else view?.showErrorMessage("taking picture failed")
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/domain/SCropImageContractJava.java b/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/domain/SCropImageContractJava.java
deleted file mode 100644
index 449c536e..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/domain/SCropImageContractJava.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.canhub.cropper.sample.crop_image_java.domain;
-
-import android.content.Context;
-import android.net.Uri;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentActivity;
-
-import com.canhub.cropper.CropImageView;
-
-public interface SCropImageContractJava {
-
- interface View {
- void showErrorMessage(String message);
- void handleCropImageResult(String uri);
- void startCameraWithUri();
- }
-
- interface Presenter {
- void bind(View view);
- void unbind();
- void onCreate(FragmentActivity activity, Context context);
- void onCropImageResult(@NonNull CropImageView.CropResult result);
- void onTakePictureResult(boolean success);
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/presenter/SCropImagePresenterJava.java b/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/presenter/SCropImagePresenterJava.java
deleted file mode 100644
index 89ad2f55..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_java/presenter/SCropImagePresenterJava.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.canhub.cropper.sample.crop_image_java.presenter;
-
-import android.content.Context;
-import android.net.Uri;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentActivity;
-
-import com.canhub.cropper.CropImage;
-import com.canhub.cropper.CropImageView;
-import com.canhub.cropper.sample.crop_image_java.domain.SCropImageContractJava;
-
-import java.util.Objects;
-
-public class SCropImagePresenterJava implements SCropImageContractJava.Presenter {
- private SCropImageContractJava.View view = null;
-
- @Override
- public void bind(SCropImageContractJava.View view) {
- this.view = view;
- }
-
- @Override
- public void unbind() {
- view = null;
- }
-
- @Override
- public void onCreate(FragmentActivity activity, Context context) {
- assert view != null;
- if (activity == null || context == null) {
- view.showErrorMessage("onCreate activity and/or context are null");
- }
- }
-
- @Override
- public void onCropImageResult(@NonNull CropImageView.CropResult result) {
- if (result.isSuccessful()) {
- view.handleCropImageResult(Objects.requireNonNull(result.getUriContent())
- .toString()
- .replace("file:", ""));
- } else if (result.equals(CropImage.CancelledResult.INSTANCE)) {
- view.showErrorMessage("cropping image was cancelled by the user");
- } else {
- view.showErrorMessage("cropping image failed");
- }
- }
-
- @Override
- public void onTakePictureResult(boolean success) {
- if (success) {
- view.startCameraWithUri();
- } else {
- view.showErrorMessage("taking picture failed");
- }
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/domain/SCropImageViewContract.kt b/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/domain/SCropImageViewContract.kt
deleted file mode 100644
index 910db09e..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/domain/SCropImageViewContract.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.canhub.cropper.sample.crop_image_view.domain
-
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsDomain
-
-internal interface SCropImageViewContract {
- fun interface View {
- fun setOptions(options: SOptionsDomain)
- }
-
- interface Presenter {
- fun bind(view: View)
- fun unbind()
- fun onViewCreated()
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/presenter/SCropImageViewPresenter.kt b/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/presenter/SCropImageViewPresenter.kt
deleted file mode 100644
index 58634338..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/crop_image_view/presenter/SCropImageViewPresenter.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.canhub.cropper.sample.crop_image_view.presenter
-
-import com.canhub.cropper.CropImageView
-import com.canhub.cropper.sample.crop_image_view.domain.SCropImageViewContract
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsDomain
-
-internal class SCropImageViewPresenter : SCropImageViewContract.Presenter {
-
- private var view: SCropImageViewContract.View? = null
-
- override fun bind(view: SCropImageViewContract.View) {
- this.view = view
- }
-
- override fun unbind() {
- view = null
- }
-
- override fun onViewCreated() {
- view?.setOptions(getOptions())
- }
-
- private fun getOptions(): SOptionsDomain = SOptionsDomain(
- CropImageView.ScaleType.FIT_CENTER,
- CropImageView.CropShape.RECTANGLE,
- CropImageView.CropCornerShape.RECTANGLE,
- CropImageView.Guidelines.ON,
- Pair(1, 1),
- autoZoom = true,
- maxZoomLvl = 2,
- multiTouch = true,
- centerMove = true,
- showCropOverlay = true,
- showProgressBar = true,
- flipHorizontal = false,
- flipVertically = false
- )
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/extend_activity/domain/SExtendContract.kt b/sample/src/main/java/com/canhub/cropper/sample/extend_activity/domain/SExtendContract.kt
deleted file mode 100644
index 3079194f..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/extend_activity/domain/SExtendContract.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.canhub.cropper.sample.extend_activity.domain
-
-internal interface SExtendContract {
- interface View {
- fun updateRotationCounter(counter: String)
- fun rotate(counter: Int)
- }
-
- interface Presenter {
- fun bindView(view: View)
- fun unbindView()
- fun onRotateClick()
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/extend_activity/presenter/SExtendPresenter.kt b/sample/src/main/java/com/canhub/cropper/sample/extend_activity/presenter/SExtendPresenter.kt
deleted file mode 100644
index 73c77acc..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/extend_activity/presenter/SExtendPresenter.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.canhub.cropper.sample.extend_activity.presenter
-
-import com.canhub.cropper.sample.extend_activity.domain.SExtendContract
-
-internal class SExtendPresenter : SExtendContract.Presenter {
-
- private var view: SExtendContract.View? = null
- private var counter = 0
-
- override fun bindView(view: SExtendContract.View) {
- this.view = view
- this.view?.updateRotationCounter(counter.toString())
- }
-
- override fun unbindView() {
- view = null
- }
-
- override fun onRotateClick() {
- counter += 90
- view?.rotate(90)
- if (counter == 360) counter = 0
- view?.updateRotationCounter(counter.toString())
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/app/SOptionsDialogBottomSheet.kt b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/SampleOptionsBottomSheet.kt
similarity index 66%
rename from sample/src/main/java/com/canhub/cropper/sample/options_dialog/app/SOptionsDialogBottomSheet.kt
rename to sample/src/main/java/com/canhub/cropper/sample/options_dialog/SampleOptionsBottomSheet.kt
index 135278e3..ce45b5e1 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/app/SOptionsDialogBottomSheet.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/SampleOptionsBottomSheet.kt
@@ -1,6 +1,5 @@
-package com.canhub.cropper.sample.options_dialog.app
+package com.canhub.cropper.sample.options_dialog
-import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
@@ -8,26 +7,25 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import com.canhub.cropper.CropImageView
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsContract
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsDomain
import com.example.croppersample.databinding.FragmentOptionsBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
-internal class SOptionsDialogBottomSheet : BottomSheetDialogFragment(), SOptionsContract.View {
+internal class SampleOptionsBottomSheet : BottomSheetDialogFragment() {
+
fun interface Listener {
- fun onOptionsApplySelected(options: SOptionsDomain)
+ fun onOptionsApplySelected(options: SampleOptionsEntity)
}
companion object {
fun show(
fragmentManager: FragmentManager,
- options: SOptionsDomain?,
+ options: SampleOptionsEntity?,
listener: Listener
) {
- this.listener = listener
- SOptionsDialogBottomSheet().apply {
+ Companion.listener = listener
+ SampleOptionsBottomSheet().apply {
arguments = Bundle().apply { putParcelable(OPTIONS_KEY, options) }
show(fragmentManager, null)
}
@@ -38,14 +36,8 @@ internal class SOptionsDialogBottomSheet : BottomSheetDialogFragment(), SOptions
private const val OPTIONS_KEY = "OPTIONS_KEY"
}
- private lateinit var presenter: SOptionsContract.Presenter
private lateinit var binding: FragmentOptionsBinding
-
- override fun onAttach(context: Context) {
- super.onAttach(context)
- val serviceLocator = SOptionsServiceLocator(context)
- presenter = serviceLocator.getPresenter()
- }
+ private lateinit var options: SampleOptionsEntity
override fun onCreateView(
inflater: LayoutInflater,
@@ -56,19 +48,98 @@ internal class SOptionsDialogBottomSheet : BottomSheetDialogFragment(), SOptions
return binding.root
}
- override fun onDismiss(dialog: DialogInterface) {
- presenter.onDismiss()
- super.onDismiss(dialog)
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- presenter.bind(this)
- val options = arguments?.getParcelable(OPTIONS_KEY)
+ options = arguments?.getParcelable(OPTIONS_KEY) ?: defaultOptions
+ updateOptions(options)
+
+ bindingActions()
+ }
+
+ private fun updateOptions(options: SampleOptionsEntity) {
+ when (options.scaleType) {
+ CropImageView.ScaleType.CENTER -> binding.scaleType.chipCenter.isChecked = true
+ CropImageView.ScaleType.FIT_CENTER -> binding.scaleType.chipFitCenter.isChecked = true
+ CropImageView.ScaleType.CENTER_INSIDE ->
+ binding.scaleType.chipCenterInside.isChecked = true
+ CropImageView.ScaleType.CENTER_CROP -> binding.scaleType.chipCenterCrop.isChecked = true
+ }
+ when (options.cornerShape) {
+ CropImageView.CropCornerShape.RECTANGLE ->
+ binding.cornerShape.chipRectangle.isChecked =
+ true
+ CropImageView.CropCornerShape.OVAL -> binding.cornerShape.chipOval.isChecked = true
+ }
+
+ when (options.cropShape) {
+ CropImageView.CropShape.RECTANGLE -> {
+ binding.cropShape.chipRectangle.isChecked = true
+ // Enabling the corner shape selection functionality only for Rectangle shape cropper for now
+ // To expose to other crop shape, we will need to for necessary changes in CropOverlay class
+ binding.cornerShape.root.visibility = View.VISIBLE
+ }
+ CropImageView.CropShape.OVAL -> {
+ binding.cropShape.chipOval.isChecked = true
+ }
+ CropImageView.CropShape.RECTANGLE_VERTICAL_ONLY ->
+ binding.cropShape.chipRectangleVerticalOnly.isChecked = true
+ CropImageView.CropShape.RECTANGLE_HORIZONTAL_ONLY ->
+ binding.cropShape.chipRectangleHorizontalOnly.isChecked = true
+ }
+
+ when (options.guidelines) {
+ CropImageView.Guidelines.OFF -> binding.guidelines.chipOff.isChecked = true
+ CropImageView.Guidelines.ON -> binding.guidelines.chipOn.isChecked = true
+ CropImageView.Guidelines.ON_TOUCH -> binding.guidelines.chipOnTouch.isChecked = true
+ }
+
+ when (options.ratio) {
+ Pair(1, 1) -> binding.ratio.chipOneOne.isChecked = true
+ Pair(4, 3) -> binding.ratio.chipFourThree.isChecked = true
+ Pair(16, 9) -> binding.ratio.chipSixteenNine.isChecked = true
+ else -> binding.ratio.chipFree.isChecked = true
+ }
+
+ when (options.maxZoomLvl) {
+ 4 -> binding.maxZoom.chipFour.isChecked = true
+ 8 -> binding.maxZoom.chipEight.isChecked = true
+ else -> binding.maxZoom.chipTwo.isChecked = true
+ }
+
+ binding.autoZoom.toggle.isChecked = options.autoZoom
+ binding.multiTouch.toggle.isChecked = options.multiTouch
+ binding.centerMoveEnabled.toggle.isChecked = options.centerMove
+ binding.cropOverlay.toggle.isChecked = options.showCropOverlay
+ binding.progressBar.toggle.isChecked = options.showProgressBar
+ binding.flipHorizontal.toggle.isChecked = options.flipHorizontal
+ binding.flipVertical.toggle.isChecked = options.flipVertically
+ binding.cropLabelText.toggle.isChecked = options.showCropLabel
+ }
- presenter.onViewCreated(options)
+ override fun onDismiss(dialog: DialogInterface) {
+ listener.onOptionsApplySelected(options)
+ super.onDismiss(dialog)
+ }
+ private val defaultOptions = SampleOptionsEntity(
+ scaleType = CropImageView.ScaleType.FIT_CENTER,
+ cropShape = CropImageView.CropShape.RECTANGLE,
+ cornerShape = CropImageView.CropCornerShape.RECTANGLE,
+ guidelines = CropImageView.Guidelines.ON,
+ ratio = Pair(1, 1),
+ maxZoomLvl = 2,
+ autoZoom = true,
+ multiTouch = true,
+ centerMove = true,
+ showCropOverlay = true,
+ showProgressBar = true,
+ flipHorizontal = false,
+ flipVertically = false,
+ showCropLabel = true
+ )
+
+ private fun bindingActions() {
binding.optionsHeader.isSelected = false
binding.optionsItemsScroll.setOnScrollChangeListener { _, _, _, _, _ ->
binding.optionsHeader.isSelected =
@@ -76,180 +147,116 @@ internal class SOptionsDialogBottomSheet : BottomSheetDialogFragment(), SOptions
}
binding.scaleType.chipCenter.setOnClickListener {
- presenter.onScaleTypeSelect(CropImageView.ScaleType.CENTER)
+ options = options.copy(scaleType = CropImageView.ScaleType.CENTER)
}
binding.scaleType.chipCenterCrop.setOnClickListener {
- presenter.onScaleTypeSelect(CropImageView.ScaleType.CENTER_CROP)
+ options = options.copy(scaleType = CropImageView.ScaleType.CENTER_CROP)
}
binding.scaleType.chipCenterInside.setOnClickListener {
- presenter.onScaleTypeSelect(CropImageView.ScaleType.CENTER_INSIDE)
+ options = options.copy(scaleType = CropImageView.ScaleType.CENTER_INSIDE)
}
binding.scaleType.chipFitCenter.setOnClickListener {
- presenter.onScaleTypeSelect(CropImageView.ScaleType.FIT_CENTER)
+ options = options.copy(scaleType = CropImageView.ScaleType.FIT_CENTER)
}
binding.cropShape.chipRectangle.setOnClickListener {
- presenter.onCropShapeSelect(CropImageView.CropShape.RECTANGLE)
+ options = options.copy(cropShape = CropImageView.CropShape.RECTANGLE)
binding.cornerShape.root.visibility = View.VISIBLE
}
binding.cropShape.chipOval.setOnClickListener {
- presenter.onCropShapeSelect(CropImageView.CropShape.OVAL)
+ options = options.copy(cropShape = CropImageView.CropShape.OVAL)
binding.cornerShape.root.visibility = View.GONE
}
binding.cropShape.chipRectangleVerticalOnly.setOnClickListener {
- presenter.onCropShapeSelect(CropImageView.CropShape.RECTANGLE_VERTICAL_ONLY)
+ options = options.copy(cropShape = CropImageView.CropShape.RECTANGLE_VERTICAL_ONLY)
binding.cornerShape.root.visibility = View.GONE
}
binding.cropShape.chipRectangleHorizontalOnly.setOnClickListener {
- presenter.onCropShapeSelect(CropImageView.CropShape.RECTANGLE_HORIZONTAL_ONLY)
+ options = options.copy(cropShape = CropImageView.CropShape.RECTANGLE_HORIZONTAL_ONLY)
binding.cornerShape.root.visibility = View.GONE
}
binding.cornerShape.chipRectangle.setOnClickListener {
- presenter.onCropCornerShapeSelect(CropImageView.CropCornerShape.RECTANGLE)
+ options = options.copy(cornerShape = CropImageView.CropCornerShape.RECTANGLE)
}
binding.cornerShape.chipOval.setOnClickListener {
- presenter.onCropCornerShapeSelect(CropImageView.CropCornerShape.OVAL)
+ options = options.copy(cornerShape = CropImageView.CropCornerShape.OVAL)
}
binding.guidelines.chipOff.setOnClickListener {
- presenter.onGuidelinesSelect(CropImageView.Guidelines.OFF)
+ options = options.copy(guidelines = CropImageView.Guidelines.OFF)
}
binding.guidelines.chipOn.setOnClickListener {
- presenter.onGuidelinesSelect(CropImageView.Guidelines.ON)
+ options = options.copy(guidelines = CropImageView.Guidelines.ON)
}
binding.guidelines.chipOnTouch.setOnClickListener {
- presenter.onGuidelinesSelect(CropImageView.Guidelines.ON_TOUCH)
+ options = options.copy(guidelines = CropImageView.Guidelines.ON_TOUCH)
}
binding.ratio.chipFree.setOnClickListener {
- presenter.onRatioSelect(null)
+ options = options.copy(ratio = null)
}
binding.ratio.chipOneOne.setOnClickListener {
- presenter.onRatioSelect(Pair(1, 1))
+ options = options.copy(ratio = Pair(1, 1))
}
binding.ratio.chipFourThree.setOnClickListener {
- presenter.onRatioSelect(Pair(16, 9))
+ options = options.copy(ratio = Pair(16, 9))
}
binding.ratio.chipSixteenNine.setOnClickListener {
- presenter.onRatioSelect(Pair(9, 16))
+ options = options.copy(ratio = Pair(9, 16))
}
binding.maxZoom.chipTwo.setOnClickListener {
- presenter.onMaxZoomLvlSelect(2)
+ options = options.copy(maxZoomLvl = 2)
}
binding.maxZoom.chipFour.setOnClickListener {
- presenter.onMaxZoomLvlSelect(4)
+ options = options.copy(maxZoomLvl = 4)
}
binding.maxZoom.chipEight.setOnClickListener {
- presenter.onMaxZoomLvlSelect(8)
+ options = options.copy(maxZoomLvl = 8)
}
binding.autoZoom.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onAutoZoomSelect(isChecked)
+ options = options.copy(autoZoom = isChecked)
}
binding.cropOverlay.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onCropOverlaySelect(isChecked)
+ options = options.copy(showCropOverlay = isChecked)
}
binding.flipHorizontal.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onFlipHorizontalSelect(isChecked)
+ options = options.copy(flipHorizontal = isChecked)
}
binding.flipVertical.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onFlipVerticallySelect(isChecked)
+ options = options.copy(flipVertically = isChecked)
}
binding.multiTouch.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onMultiTouchSelect(isChecked)
+ options = options.copy(multiTouch = isChecked)
}
binding.centerMoveEnabled.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onCenterMoveSelect(isChecked)
+ options = options.copy(centerMove = isChecked)
}
binding.progressBar.toggle.setOnCheckedChangeListener { _, isChecked ->
- presenter.onProgressBarSelect(isChecked)
- }
- }
-
- override fun updateOptions(options: SOptionsDomain) {
-
- when (options.scaleType) {
- CropImageView.ScaleType.CENTER -> binding.scaleType.chipCenter.isChecked = true
- CropImageView.ScaleType.FIT_CENTER -> binding.scaleType.chipFitCenter.isChecked = true
- CropImageView.ScaleType.CENTER_INSIDE ->
- binding.scaleType.chipCenterInside.isChecked = true
- CropImageView.ScaleType.CENTER_CROP -> binding.scaleType.chipCenterCrop.isChecked = true
- }
- when (options.cornerShape) {
- CropImageView.CropCornerShape.RECTANGLE -> binding.cornerShape.chipRectangle.isChecked = true
- CropImageView.CropCornerShape.OVAL -> binding.cornerShape.chipOval.isChecked = true
- }
-
- when (options.cropShape) {
- CropImageView.CropShape.RECTANGLE -> {
- binding.cropShape.chipRectangle.isChecked = true
- // Enabling the corner shape selection functionality only for Rectangle shape cropper for now
- // To expose to other crop shape, we will need to for necessary changes in CropOverlay class
- binding.cornerShape.root.visibility = View.VISIBLE
- }
- CropImageView.CropShape.OVAL -> {
- binding.cropShape.chipOval.isChecked = true
- }
- CropImageView.CropShape.RECTANGLE_VERTICAL_ONLY ->
- binding.cropShape.chipRectangleVerticalOnly.isChecked = true
- CropImageView.CropShape.RECTANGLE_HORIZONTAL_ONLY ->
- binding.cropShape.chipRectangleHorizontalOnly.isChecked = true
- }
-
- when (options.guidelines) {
- CropImageView.Guidelines.OFF -> binding.guidelines.chipOff.isChecked = true
- CropImageView.Guidelines.ON -> binding.guidelines.chipOn.isChecked = true
- CropImageView.Guidelines.ON_TOUCH -> binding.guidelines.chipOnTouch.isChecked = true
- }
-
- when (options.ratio) {
- Pair(1, 1) -> binding.ratio.chipOneOne.isChecked = true
- Pair(4, 3) -> binding.ratio.chipFourThree.isChecked = true
- Pair(16, 9) -> binding.ratio.chipSixteenNine.isChecked = true
- else -> binding.ratio.chipFree.isChecked = true
+ options = options.copy(showProgressBar = isChecked)
}
-
- when (options.maxZoomLvl) {
- 4 -> binding.maxZoom.chipFour.isChecked = true
- 8 -> binding.maxZoom.chipEight.isChecked = true
- else -> binding.maxZoom.chipTwo.isChecked = true
+ binding.cropLabelText.toggle.setOnCheckedChangeListener { _, isChecked ->
+ options = options.copy(showCropLabel = isChecked)
}
-
- binding.autoZoom.toggle.isChecked = options.autoZoom
- binding.multiTouch.toggle.isChecked = options.multiTouch
- binding.centerMoveEnabled.toggle.isChecked = options.centerMove
- binding.cropOverlay.toggle.isChecked = options.showCropOverlay
- binding.progressBar.toggle.isChecked = options.showProgressBar
- binding.flipHorizontal.toggle.isChecked = options.flipHorizontal
- binding.flipVertical.toggle.isChecked = options.flipVertically
- }
-
- override fun closeWithResult(options: SOptionsDomain) {
- listener.onOptionsApplySelected(options)
- }
-
- override fun onDestroy() {
- presenter.unbind()
- super.onDestroy()
}
}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/domain/SOptionsDomain.kt b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/SampleOptionsEntity.kt
similarity index 84%
rename from sample/src/main/java/com/canhub/cropper/sample/options_dialog/domain/SOptionsDomain.kt
rename to sample/src/main/java/com/canhub/cropper/sample/options_dialog/SampleOptionsEntity.kt
index 38b0ffb8..0e7597df 100644
--- a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/domain/SOptionsDomain.kt
+++ b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/SampleOptionsEntity.kt
@@ -1,4 +1,4 @@
-package com.canhub.cropper.sample.options_dialog.domain
+package com.canhub.cropper.sample.options_dialog
import android.os.Parcelable
import com.canhub.cropper.CropImageView
@@ -6,7 +6,7 @@ import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.RawValue
@Parcelize
-internal data class SOptionsDomain(
+internal data class SampleOptionsEntity(
val scaleType: CropImageView.ScaleType,
val cropShape: CropImageView.CropShape,
val cornerShape: CropImageView.CropCornerShape,
@@ -20,4 +20,5 @@ internal data class SOptionsDomain(
val showProgressBar: Boolean,
val flipHorizontal: Boolean,
val flipVertically: Boolean,
+ val showCropLabel: Boolean
) : Parcelable
diff --git a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/app/SOptionsServiceLocator.kt b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/app/SOptionsServiceLocator.kt
deleted file mode 100644
index 152f526e..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/app/SOptionsServiceLocator.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.canhub.cropper.sample.options_dialog.app
-
-import android.content.Context
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsContract
-import com.canhub.cropper.sample.options_dialog.presenter.SOptionsPresenter
-
-internal class SOptionsServiceLocator(private val context: Context) {
-
- fun getPresenter(): SOptionsContract.Presenter = SOptionsPresenter()
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/domain/SOptionsContract.kt b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/domain/SOptionsContract.kt
deleted file mode 100644
index 2f952f07..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/domain/SOptionsContract.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.canhub.cropper.sample.options_dialog.domain
-
-import com.canhub.cropper.CropImageView
-import com.canhub.cropper.CropImageView.CropShape
-import com.canhub.cropper.CropImageView.Guidelines
-import com.canhub.cropper.CropImageView.ScaleType
-
-internal interface SOptionsContract {
-
- interface View {
- fun updateOptions(options: SOptionsDomain)
- fun closeWithResult(options: SOptionsDomain)
- }
-
- interface Presenter {
- fun bind(view: View)
- fun unbind()
- fun onViewCreated(options: SOptionsDomain?)
- fun onDismiss()
- fun onScaleTypeSelect(scaleType: ScaleType)
- fun onCropShapeSelect(cropShape: CropShape)
- fun onCropCornerShapeSelect(cornerShape: CropImageView.CropCornerShape)
- fun onGuidelinesSelect(guidelines: Guidelines)
- fun onRatioSelect(ratio: Pair?)
- fun onAutoZoomSelect(enable: Boolean)
- fun onMaxZoomLvlSelect(maxZoom: Int)
- fun onMultiTouchSelect(enable: Boolean)
- fun onCenterMoveSelect(enable: Boolean)
- fun onCropOverlaySelect(show: Boolean)
- fun onProgressBarSelect(show: Boolean)
- fun onFlipHorizontalSelect(enable: Boolean)
- fun onFlipVerticallySelect(enable: Boolean)
- }
-}
diff --git a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/presenter/SOptionsPresenter.kt b/sample/src/main/java/com/canhub/cropper/sample/options_dialog/presenter/SOptionsPresenter.kt
deleted file mode 100644
index 94e36878..00000000
--- a/sample/src/main/java/com/canhub/cropper/sample/options_dialog/presenter/SOptionsPresenter.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.canhub.cropper.sample.options_dialog.presenter
-
-import com.canhub.cropper.CropImageView
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsContract
-import com.canhub.cropper.sample.options_dialog.domain.SOptionsDomain
-
-internal class SOptionsPresenter : SOptionsContract.Presenter {
-
- private var view: SOptionsContract.View? = null
- private var options = defaultOptions()
-
- override fun bind(view: SOptionsContract.View) {
- this.view = view
- }
-
- override fun unbind() {
- view = null
- }
-
- override fun onViewCreated(options: SOptionsDomain?) {
- options?.let { this.options = options }
- view?.updateOptions(this.options)
- }
-
- override fun onDismiss() {
- view?.closeWithResult(options)
- }
-
- override fun onScaleTypeSelect(scaleType: CropImageView.ScaleType) {
- options = options.copy(scaleType = scaleType)
- }
-
- override fun onCropShapeSelect(cropShape: CropImageView.CropShape) {
- options = options.copy(cropShape = cropShape)
- }
-
- override fun onGuidelinesSelect(guidelines: CropImageView.Guidelines) {
- options = options.copy(guidelines = guidelines)
- }
-
- override fun onRatioSelect(ratio: Pair?) {
- options = options.copy(ratio = ratio)
- }
-
- override fun onAutoZoomSelect(enable: Boolean) {
- options = options.copy(autoZoom = enable)
- }
-
- override fun onMaxZoomLvlSelect(maxZoom: Int) {
- options = options.copy(maxZoomLvl = maxZoom)
- }
-
- override fun onMultiTouchSelect(enable: Boolean) {
- options = options.copy(multiTouch = enable)
- }
-
- override fun onCenterMoveSelect(enable: Boolean) {
- options = options.copy(centerMove = enable)
- }
-
- override fun onCropOverlaySelect(show: Boolean) {
- options = options.copy(showCropOverlay = show)
- }
-
- override fun onProgressBarSelect(show: Boolean) {
- options = options.copy(showProgressBar = show)
- }
-
- override fun onFlipHorizontalSelect(enable: Boolean) {
- options = options.copy(flipHorizontal = enable)
- }
-
- override fun onFlipVerticallySelect(enable: Boolean) {
- options = options.copy(flipVertically = enable)
- }
- override fun onCropCornerShapeSelect(cornerShape: CropImageView.CropCornerShape) {
- options = options.copy(cornerShape = cornerShape)
- }
-
- private fun defaultOptions() = SOptionsDomain(
- CropImageView.ScaleType.FIT_CENTER,
- CropImageView.CropShape.RECTANGLE,
- CropImageView.CropCornerShape.RECTANGLE,
- CropImageView.Guidelines.ON,
- Pair(1, 1),
- maxZoomLvl = 2,
- autoZoom = true,
- multiTouch = true,
- centerMove = true,
- showCropOverlay = true,
- showProgressBar = true,
- flipHorizontal = false,
- flipVertically = false
- )
-}
diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml
index fa84ca47..3d2018b7 100644
--- a/sample/src/main/res/layout/activity_main.xml
+++ b/sample/src/main/res/layout/activity_main.xml
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="com.canhub.cropper.sample.SMainActivity">
+ tools:context="com.canhub.cropper.sample.MainActivity">
-
@@ -24,6 +24,10 @@
app:cropCornerRadius="@dimen/default_crop_corner_radius"
app:cropBorderCornerOffset="@dimen/default_crop_corner_offset"
app:cropBorderCornerThickness="@dimen/default_crop_corner_offset"
+ app:cropShowLabel="true"
+ app:cropperLabelText="@string/default_crop_label_text"
+ app:cropperLabelTextSize="@dimen/default_crop_text_size"
+ app:cropBorderCornerColor="@color/cardview_shadow_start_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
diff --git a/sample/src/main/res/layout/fragment_options.xml b/sample/src/main/res/layout/fragment_options.xml
index 06db3d79..0e3c2e08 100644
--- a/sample/src/main/res/layout/fragment_options.xml
+++ b/sample/src/main/res/layout/fragment_options.xml
@@ -95,6 +95,9 @@
+
\ No newline at end of file
diff --git a/sample/src/main/res/layout/switch_crop_text_label.xml b/sample/src/main/res/layout/switch_crop_text_label.xml
new file mode 100644
index 00000000..ca675818
--- /dev/null
+++ b/sample/src/main/res/layout/switch_crop_text_label.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/values/dimens.xml b/sample/src/main/res/values/dimens.xml
index fbc3b9c2..e63ff37a 100644
--- a/sample/src/main/res/values/dimens.xml
+++ b/sample/src/main/res/values/dimens.xml
@@ -39,4 +39,5 @@
8dp
8dp
4dp
+ 20sp
\ No newline at end of file
diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml
index 497af191..b8bba517 100644
--- a/sample/src/main/res/values/strings.xml
+++ b/sample/src/main/res/values/strings.xml
@@ -91,4 +91,6 @@
This is a sample code using the library. The sample here is for extend CropImageActivity, to be about to custom build your personal view around it. For that we need to use CropImageView.
Click to change rotation: %1$s
Corner Shape
+ Show Crop Label Text
+ Sample crop label
diff --git a/versions.gradle b/versions.gradle
index 475b28d7..1c0c38de 100644
--- a/versions.gradle
+++ b/versions.gradle
@@ -1,7 +1,7 @@
ext {
// Project
- libVersion = "4.2.1"
+ libVersion = "4.3.0"
compileSdkVersion = 31
targetSdkVersion = 31
minSdkVersion = 16