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

Zoom #74

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import android.widget.Toast
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.Preview
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ fun ImageProxy.toBitmap(): Bitmap {
val bytes = ByteArray(buffer.remaining())
buffer.get(bytes)
return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ class ChoiceBuilder private constructor(
choiceSpec.orientation = orientation
}

/**
* Sets the maximum scale factor for zoom in preview
* Zoom will be disabled in preview if value is set to 1f
*
* @param previewMaxScaleFactor Float default is 1f
* @return [ChoiceBuilder] instance
*/
fun previewMaxScaleFactor(previewMaxScaleFactor: Float): ChoiceBuilder =
apply {
choiceSpec.previewMaxScaleFactor = previewMaxScaleFactor
}

/**
* Opens media selection with the requestCode provided
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ChoiceSpec private constructor() {
var showDeviceCamera: Boolean = false
var showCameraFirst: Boolean = false
var orientation: Int = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
var previewMaxScaleFactor: Float = 1f

private object InstanceHolder {
val INSTANCE = ChoiceSpec()
Expand Down Expand Up @@ -44,5 +45,6 @@ class ChoiceSpec private constructor() {
showDeviceCamera = false
showCameraFirst = false
orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
previewMaxScaleFactor = 1f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class MediaGalleryFragment : Fragment(), MediaCellListener {

override fun onMediaCellClicked(displayModel: MediaCellDisplayModel) {
if (displayModel.id == CAMERA_CAPTURE_ID)
(requireActivity() as? ShergilActivity)?.askPermissionAndOpenCameraCapture()
(requireActivity() as? ShergilActivity)?.askPermissionAndOpenCameraCapture()
kinnerapriyap marked this conversation as resolved.
Show resolved Hide resolved
else
viewModel.setMediaChecked(displayModel)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
package com.kinnerapriyap.sugar.mediapreview

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.kinnerapriyap.sugar.R
import com.kinnerapriyap.sugar.databinding.ViewMediaObjectPreviewBinding
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.kinnerapriyap.sugar.mediagallery.cell.MediaCellDisplayModel

class MediaPreviewAdapter(
private val mediaObjectPreviewListener: MediaObjectPreviewListener
) : RecyclerView.Adapter<MediaPreviewAdapter.MediaPreviewObjectHolder>() {
class MediaPreviewAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

var selectedMedia: List<MediaCellDisplayModel> = listOf()
set(value) {
Expand All @@ -20,30 +14,6 @@ class MediaPreviewAdapter(

override fun getItemCount(): Int = selectedMedia.size

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): MediaPreviewObjectHolder {
val binding = DataBindingUtil.inflate<ViewMediaObjectPreviewBinding>(
LayoutInflater.from(parent.context),
R.layout.view_media_object_preview,
parent,
false
)
return MediaPreviewObjectHolder(binding)
}

override fun onBindViewHolder(holder: MediaPreviewObjectHolder, position: Int) {
holder.bind(selectedMedia[position], mediaObjectPreviewListener)
}

inner class MediaPreviewObjectHolder(
private val binding: ViewMediaObjectPreviewBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(displayModel: MediaCellDisplayModel, listener: MediaObjectPreviewListener) {
binding.displayModel = displayModel
binding.listener = listener
binding.executePendingBindings()
}
}
override fun createFragment(position: Int): Fragment =
MediaPreviewPageFragment.createInstance(selectedMedia[position])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.kinnerapriyap.sugar.mediapreview
kinnerapriyap marked this conversation as resolved.
Show resolved Hide resolved

import android.os.Bundle
kinnerapriyap marked this conversation as resolved.
Show resolved Hide resolved
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.kinnerapriyap.sugar.R
import com.kinnerapriyap.sugar.ShergilViewModel
import com.kinnerapriyap.sugar.databinding.FragmentMediaPreviewPageBinding
import com.kinnerapriyap.sugar.mediagallery.cell.MediaCellDisplayModel

class MediaPreviewPageFragment : Fragment(), View.OnTouchListener {

private val viewModel: ShergilViewModel by activityViewModels()

private var binding: FragmentMediaPreviewPageBinding? = null

private var scaleFactor = 1f

private lateinit var scaleListener: ScaleGestureDetector.SimpleOnScaleGestureListener

private val scaleDetector by lazy {
ScaleGestureDetector(context, scaleListener)
}

private val displayModel: MediaCellDisplayModel?
get() = arguments?.getParcelable(MEDIA_CELL_DISPLAY_MODEL)

companion object {
private const val MEDIA_CELL_DISPLAY_MODEL = "media_cell_display_model"

@JvmStatic
fun createInstance(displayModel: MediaCellDisplayModel) =
MediaPreviewPageFragment().apply {
arguments = Bundle().apply {
putParcelable(MEDIA_CELL_DISPLAY_MODEL, displayModel)
}
}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_media_preview_page,
container,
false
)
binding?.root?.setOnTouchListener(this)
return binding?.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.displayModel = displayModel
binding?.listener = parentFragment as? MediaPreviewFragment
scaleListener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {

override fun onScale(detector: ScaleGestureDetector): Boolean {
scaleFactor *= detector.scaleFactor
scaleFactor =
1f.coerceAtLeast(
scaleFactor.coerceAtMost(
viewModel.getChoiceSpec().previewMaxScaleFactor
)
)
binding?.imageView?.scaleX = scaleFactor
binding?.imageView?.scaleY = scaleFactor
return true
}
}
}

override fun onTouch(v: View?, event: MotionEvent?): Boolean {
scaleDetector.onTouchEvent(event)
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
android:layout_height="match_parent">

<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/preivewCheckBox"
android:id="@+id/previewCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@{displayModel.isChecked}"
Expand All @@ -39,6 +39,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/preivewCheckBox" />
app:layout_constraintTop_toBottomOf="@id/previewCheckBox" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>