From 455920d8851efa9ba167c6a79954de9e9923ff0c Mon Sep 17 00:00:00 2001 From: Arkadiusz Chmura Date: Mon, 21 Mar 2022 16:14:42 +0100 Subject: [PATCH] Preserve state across configuration changes (#335) * Preserve the loaded bitmap uri across configuration changes * Preserve the latestTmpUri variable across configuration changes --- CHANGELOG.md | 1 + .../com/canhub/cropper/CropImageActivity.kt | 12 ++++++++ .../java/com/canhub/cropper/CropImageView.kt | 28 ++++++++----------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 713b560b..8ed5b587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [4.2.0] - unreleased ### Fixed - Added missing support for `ScaleType.CENTER_CROP` [#220](https://github.com/CanHub/Android-Image-Cropper/issues/220) +- State is now preserved across configuration changes [#296](https://github.com/CanHub/Android-Image-Cropper/issues/296) ### Added - Added an option to skip manual editing and return entire image when required [#324](https://github.com/CanHub/Android-Image-Cropper/pull/324) diff --git a/cropper/src/main/java/com/canhub/cropper/CropImageActivity.kt b/cropper/src/main/java/com/canhub/cropper/CropImageActivity.kt index 72eca958..42f5ee4c 100644 --- a/cropper/src/main/java/com/canhub/cropper/CropImageActivity.kt +++ b/cropper/src/main/java/com/canhub/cropper/CropImageActivity.kt @@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.graphics.BlendModeColorFilterCompat import androidx.core.graphics.BlendModeCompat +import androidx.core.net.toUri import com.canhub.cropper.CropImageView.CropResult import com.canhub.cropper.CropImageView.OnCropImageCompleteListener import com.canhub.cropper.CropImageView.OnSetImageUriCompleteListener @@ -71,6 +72,8 @@ open class CropImageActivity : else -> finish() } } else cropImageView?.setImageUriAsync(cropImageUri) + } else { + latestTmpUri = savedInstanceState.getString(BUNDLE_KEY_TMP_URI)?.toUri() } supportActionBar?.let { @@ -134,6 +137,11 @@ open class CropImageActivity : cropImageView?.setOnCropImageCompleteListener(null) } + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putString(BUNDLE_KEY_TMP_URI, latestTmpUri.toString()) + } + override fun onCreateOptionsMenu(menu: Menu): Boolean { if (cropImageOptions.skipEditing) return true menuInflater.inflate(R.menu.crop_image_menu, menu) @@ -323,4 +331,8 @@ open class CropImageActivity : } enum class Source { CAMERA, GALLERY } + + private companion object { + const val BUNDLE_KEY_TMP_URI = "bundle_key_tmp_uri" + } } diff --git a/cropper/src/main/java/com/canhub/cropper/CropImageView.kt b/cropper/src/main/java/com/canhub/cropper/CropImageView.kt index 2bf5927e..7033b52c 100644 --- a/cropper/src/main/java/com/canhub/cropper/CropImageView.kt +++ b/cropper/src/main/java/com/canhub/cropper/CropImageView.kt @@ -162,12 +162,6 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute */ private var mSizeChanged = false - /** - * Temp URI used to save bitmap image to disk to preserve for instance state in case cropped was - * set with bitmap - */ - private var saveInstanceStateBitmapUri: Uri? = null - /** Task used to load bitmap async from UI thread */ private var bitmapLoadingWorkerJob: WeakReference? = null @@ -933,7 +927,6 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute mZoomOffsetX = 0f mZoomOffsetY = 0f mImageMatrix.reset() - saveInstanceStateBitmapUri = null mRestoreCropWindowRect = null mRestoreDegreesRotated = 0 imageView.setImageBitmap(null) @@ -1008,14 +1001,17 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute return super.onSaveInstanceState() } val bundle = Bundle() - if (isSaveBitmapToInstanceState && saveInstanceStateBitmapUri == null && mImageResource < 1) { - saveInstanceStateBitmapUri = BitmapUtils.writeTempStateStoreBitmap( - context = context, - bitmap = originalBitmap, - customOutputUri = customOutputUri - ) - } - if (saveInstanceStateBitmapUri != null && originalBitmap != null) { + val loadedImageUri = + if (isSaveBitmapToInstanceState && imageUri == null && mImageResource < 1) { + BitmapUtils.writeTempStateStoreBitmap( + context = context, + bitmap = originalBitmap, + customOutputUri = customOutputUri + ) + } else { + imageUri + } + if (loadedImageUri != null && originalBitmap != null) { val key = UUID.randomUUID().toString() BitmapUtils.mStateBitmap = Pair(key, WeakReference(originalBitmap)) bundle.putString("LOADED_IMAGE_STATE_BITMAP_KEY", key) @@ -1027,7 +1023,7 @@ class CropImageView @JvmOverloads constructor(context: Context, attrs: Attribute } } bundle.putParcelable("instanceState", super.onSaveInstanceState()) - bundle.putParcelable("LOADED_IMAGE_URI", saveInstanceStateBitmapUri) + bundle.putParcelable("LOADED_IMAGE_URI", loadedImageUri) bundle.putInt("LOADED_IMAGE_RESOURCE", mImageResource) bundle.putInt("LOADED_SAMPLE_SIZE", loadedSampleSize) bundle.putInt("DEGREES_ROTATED", mDegreesRotated)