Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve state across configuration changes #335

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
12 changes: 12 additions & 0 deletions cropper/src/main/java/com/canhub/cropper/CropImageActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -71,6 +72,8 @@ open class CropImageActivity :
else -> finish()
}
} else cropImageView?.setImageUriAsync(cropImageUri)
} else {
latestTmpUri = savedInstanceState.getString(BUNDLE_KEY_TMP_URI)?.toUri()
}

supportActionBar?.let {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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"
}
}
28 changes: 12 additions & 16 deletions cropper/src/main/java/com/canhub/cropper/CropImageView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<BitmapLoadingWorkerJob>? = null

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down