fix crash due to IndexOutOfBounds on the MaterialToggleGroup

- this seems like a bug on the MaterialToggleGroup; for example, when 4 items are added to it and removed and later on 3 items added, it will crash
- the only feasible fix is to create a new MaterialToggleGroup when displaying the options
- calling invalidate, removeAllViews, etc do not work
This commit is contained in:
darthpaul
2022-10-06 11:09:45 +01:00
parent 315f8f559c
commit 50601ca31b
3 changed files with 27 additions and 35 deletions

View File

@ -22,6 +22,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.simplemobiletools.camera.BuildConfig import com.simplemobiletools.camera.BuildConfig
import com.simplemobiletools.camera.R import com.simplemobiletools.camera.R
@ -43,7 +44,6 @@ import kotlinx.android.synthetic.main.layout_flash.flash_auto
import kotlinx.android.synthetic.main.layout_flash.flash_off import kotlinx.android.synthetic.main.layout_flash.flash_off
import kotlinx.android.synthetic.main.layout_flash.flash_on import kotlinx.android.synthetic.main.layout_flash.flash_on
import kotlinx.android.synthetic.main.layout_flash.flash_toggle_group import kotlinx.android.synthetic.main.layout_flash.flash_toggle_group
import kotlinx.android.synthetic.main.layout_media_size.media_size_toggle_group
import kotlinx.android.synthetic.main.layout_top.change_resolution import kotlinx.android.synthetic.main.layout_top.change_resolution
import kotlinx.android.synthetic.main.layout_top.default_icons import kotlinx.android.synthetic.main.layout_top.default_icons
import kotlinx.android.synthetic.main.layout_top.settings import kotlinx.android.synthetic.main.layout_top.settings
@ -58,12 +58,12 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
lateinit var mTimerHandler: Handler lateinit var mTimerHandler: Handler
private lateinit var defaultScene: Scene private lateinit var defaultScene: Scene
private lateinit var mediaSizeScene: Scene
private lateinit var flashModeScene: Scene private lateinit var flashModeScene: Scene
private lateinit var mOrientationEventListener: OrientationEventListener private lateinit var mOrientationEventListener: OrientationEventListener
private lateinit var mFocusCircleView: FocusCircleView private lateinit var mFocusCircleView: FocusCircleView
private lateinit var mCameraImpl: MyCameraImpl private lateinit var mCameraImpl: MyCameraImpl
private var mPreview: MyPreview? = null private var mPreview: MyPreview? = null
private var mediaSizeToggleGroup: MaterialButtonToggleGroup? = null
private var mPreviewUri: Uri? = null private var mPreviewUri: Uri? = null
private var mIsInPhotoMode = true private var mIsInPhotoMode = true
private var mIsCameraAvailable = false private var mIsCameraAvailable = false
@ -287,12 +287,17 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
} }
} }
private fun createToggleGroup(): MaterialButtonToggleGroup {
return MaterialButtonToggleGroup(this).apply {
isSingleSelection = true
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
}
private fun initializeCamera() { private fun initializeCamera() {
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
initButtons() initButtons()
defaultScene = Scene(top_options, default_icons) defaultScene = Scene(top_options, default_icons)
mediaSizeScene = Scene(top_options, media_size_toggle_group)
flashModeScene = Scene(top_options, flash_toggle_group) flashModeScene = Scene(top_options, flash_toggle_group)
ViewCompat.setOnApplyWindowInsetsListener(view_holder) { _, windowInsets -> ViewCompat.setOnApplyWindowInsetsListener(view_holder) { _, windowInsets ->
@ -725,13 +730,14 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
} }
private fun closeOptions(): Boolean { private fun closeOptions(): Boolean {
if (media_size_toggle_group.isVisible() || if (mediaSizeToggleGroup?.isVisible() == true ||
flash_toggle_group.isVisible() flash_toggle_group.isVisible()
) { ) {
val transitionSet = createTransition() val transitionSet = createTransition()
TransitionManager.go(defaultScene, transitionSet) TransitionManager.go(defaultScene, transitionSet)
media_size_toggle_group.beGone() mediaSizeToggleGroup?.beGone()
flash_toggle_group.beGone() flash_toggle_group.beGone()
default_icons.beVisible()
return true return true
} }
@ -752,8 +758,11 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
onSelect: (index: Int, changed: Boolean) -> Unit onSelect: (index: Int, changed: Boolean) -> Unit
) { ) {
media_size_toggle_group.removeAllViews() top_options.removeView(mediaSizeToggleGroup)
media_size_toggle_group.clearChecked() val mediaSizeToggleGroup = createToggleGroup().apply {
mediaSizeToggleGroup = this
}
top_options.addView(mediaSizeToggleGroup)
val onItemClick = { clickedViewId: Int -> val onItemClick = { clickedViewId: Int ->
closeOptions() closeOptions()
@ -764,11 +773,17 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
resolutions.map { resolutions.map {
createButton(it, onItemClick) createButton(it, onItemClick)
}.forEach { button -> }.forEach { button ->
media_size_toggle_group.addView(button) mediaSizeToggleGroup.addView(button)
} }
media_size_toggle_group.check(selectedResolution.buttonViewId) mediaSizeToggleGroup.check(selectedResolution.buttonViewId)
showResolutionOptions()
val transitionSet = createTransition()
val mediaSizeScene = Scene(top_options, mediaSizeToggleGroup)
TransitionManager.go(mediaSizeScene, transitionSet)
default_icons.beGone()
mediaSizeToggleGroup.beVisible()
mediaSizeToggleGroup.children.map { it as MaterialButton }.forEach(::setButtonColors)
} }
private fun createButton(resolutionOption: ResolutionOption, onClick: (clickedViewId: Int) -> Unit): MaterialButton { private fun createButton(resolutionOption: ResolutionOption, onClick: (clickedViewId: Int) -> Unit): MaterialButton {
@ -786,13 +801,6 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
} }
} }
private fun showResolutionOptions() {
val transitionSet = createTransition()
TransitionManager.go(mediaSizeScene, transitionSet)
media_size_toggle_group.beVisible()
media_size_toggle_group.children.map { it as MaterialButton }.forEach(::setButtonColors)
}
private fun createTransition(): Transition { private fun createTransition(): Transition {
val fadeTransition = Fade() val fadeTransition = Fade()
return TransitionSet().apply { return TransitionSet().apply {

View File

@ -31,12 +31,7 @@
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<include layout="@layout/layout_top" /> <include layout="@layout/layout_top" />
<include layout="@layout/layout_flash" />
<include layout="@layout/layout_media_size" />
<include
layout="@layout/layout_flash"
android:visibility="gone" />
</FrameLayout> </FrameLayout>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.button.MaterialButtonToggleGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/media_size_toggle_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:selectionRequired="true"
android:visibility="gone"
tools:visibility="visible"
app:singleSelection="true" />