diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt index d1f184e9..e46440a1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/activities/MainActivity.kt @@ -12,6 +12,7 @@ import android.os.CountDownTimer import android.provider.MediaStore import android.view.* import android.widget.LinearLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.core.content.ContextCompat import androidx.core.view.* import androidx.transition.* @@ -325,7 +326,9 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera initInPhotoMode = isInPhotoMode, ) - mFocusCircleView = FocusCircleView(this) + mFocusCircleView = FocusCircleView(this).apply { + id = View.generateViewId() + } view_holder.addView(mFocusCircleView) setupPreviewImage(true) @@ -411,20 +414,15 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera @SuppressLint("ClickableViewAccessibility") private fun initModeSwitcher() { - val gestureDetector = GestureDetectorCompat(this, object : GestureDetector.SimpleOnGestureListener() { + val gestureDetector = GestureDetectorCompat(this, object : GestureDetectorListener() { override fun onDown(e: MotionEvent): Boolean { // we have to return true here so ACTION_UP // (and onFling) can be dispatched return true } - override fun onFling(event1: MotionEvent, event2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { - // these can be null even if the docs say they cannot, getting event1.x in itself can cause crashes - try { - if (event1 == null || event2 == null || event1.x == null || event2.x == null) { - return true - } - } catch (e: NullPointerException) { + override fun onFling(event1: MotionEvent?, event2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { + if (event1 == null || event2 == null) { return true } @@ -824,6 +822,19 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera button.iconTint = ColorStateList(states, iconColors) } + override fun adjustPreviewView(requiresCentering: Boolean) { + val constraintSet = ConstraintSet() + constraintSet.clone(view_holder) + if (requiresCentering) { + constraintSet.connect(preview_view.id, ConstraintSet.TOP, top_options.id, ConstraintSet.BOTTOM) + constraintSet.connect(preview_view.id, ConstraintSet.BOTTOM, camera_mode_tab.id, ConstraintSet.TOP) + } else { + constraintSet.connect(preview_view.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP) + constraintSet.connect(preview_view.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM) + } + constraintSet.applyTo(view_holder) + } + override fun mediaSaved(path: String) { rescanPaths(arrayListOf(path)) { setupPreviewImage(true) diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/helpers/GestureDetectorListener.java b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/GestureDetectorListener.java new file mode 100644 index 00000000..209a9a20 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/camera/helpers/GestureDetectorListener.java @@ -0,0 +1,13 @@ +package com.simplemobiletools.camera.helpers; + +import android.view.GestureDetector; +import android.view.MotionEvent; + +import androidx.annotation.Nullable; + +public class GestureDetectorListener extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onFling(@Nullable MotionEvent e1, @Nullable MotionEvent e2, float velocityX, float velocityY) { + return super.onFling(e1, e2, velocityX, velocityY); + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt index 0e237a30..b9295223 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreview.kt @@ -161,6 +161,8 @@ class CameraXPreview( MySize(selectedQuality.width, selectedQuality.height) } + listener.adjustPreviewView(resolution.requiresCentering()) + val isFullSize = resolution.isFullScreen previewView.scaleType = if (isFullSize) ScaleType.FILL_CENTER else ScaleType.FIT_CENTER val rotation = previewView.display.rotation diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt index 1abcc617..a13f7387 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/implementations/CameraXPreviewListener.kt @@ -30,6 +30,6 @@ interface CameraXPreviewListener { isFrontCamera: Boolean, onSelect: (index: Int, changed: Boolean) -> Unit, ) - fun showFlashOptions(photoCapture: Boolean) + fun adjustPreviewView(requiresCentering: Boolean) } diff --git a/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt b/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt index 4201aa8d..265bcab7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt +++ b/app/src/main/kotlin/com/simplemobiletools/camera/models/MySize.kt @@ -17,6 +17,10 @@ data class MySize(val width: Int, val height: Int, val isFullScreen: Boolean = f val megaPixels: String = String.format("%.1f", (width * height.toFloat()) / ONE_MEGA_PIXEL) + fun requiresCentering(): Boolean { + return !isFullScreen && (isFourToThree() || isThreeToTwo() || isSquare()) + } + fun isSixteenToNine() = ratio == 16 / 9f private fun isFiveToThree() = ratio == 5 / 3f diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 5d38d5a2..c0275935 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -11,7 +11,9 @@ + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toTopOf="parent" />