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

[FEATURE] Larger range for App Drawer 'Row height' (lower minimum value) #4663

Closed
tgex0 opened this issue Aug 17, 2024 · 9 comments
Closed

Comments

@tgex0
Copy link
Contributor

tgex0 commented Aug 17, 2024

Describe the feature

I'd like a lower minimum value for App Drawer 'Row height'.
I have a grid of 8 columns of icons (at 70% size) in the app drawer and find that the smallest 'Row height' of 70% still leaves a lot of space between the rows.
Having experimented with different values, I've found that a 'Row Height' of 50% works great for this scenario.

Why would it be useful to add?

Gives the user greater flexibility in configuring the app drawer.

Did the feature exist in Lawnchair v2? (Play Store version)

No

Example(s)

Current lowest value of 70%:

Screenshot_2024-08-17-22-51-30-250_app lawnchair

With lower value of 50%:

Screenshot_2024-08-17-22-51-40-930_app lawnchair

Additional context

No response

@charliefrance
Copy link

How did you change it to 50%? 70% is much too large, I want to match it with my 7x15 homescreen

@tgex0
Copy link
Contributor Author

tgex0 commented Aug 21, 2024

How did you change it to 50%? 70% is much too large, I want to match it with my 7x15 homescreen

I forked the project, changed the source and built a new APK.
All I did was change the slider's range in the UI (lawnchair\src\app\lawnchair\ui\preferences\destinations\AppDrawerPreferences.kt).
I have no idea if it'll have any unwanted knock-on effects but it seems to work fine for me.

@tepozoa
Copy link

tepozoa commented Aug 25, 2024

I've just upgraded to 0.14 beta 3 and it seems to have changed since beta2 - I'd never touched the row height before, but the App Drawer felt instantly different in how much space was between icons vertically. I have 2x Pixel 6a (stock ROMs), the one running the stock Pixel launcher still has a tighter row height than Lawnchair 0.14beta3 at 70%.

To my untrained eye, a setting of 60% or 50% allowed in Lawnchair row height should/would match the default Android 14 Pixel 6a row height density when holding my two devices side by side, using a column count of 5 wide. $0.02

UPDATE: I discovered the root cause thanks to the above comment pointing at which source code they tweaked to test; it's this commit implementing two-line labels in the App Drawer, which is enabled by default in 0.14 beta 3: 7c34d0c

Disabling that new setting (located at the very bottom of the App Drawer settings screen) restores the app drawer icon density to it's former glory at 100% row height and matches the stock Pixel launcher again as expected. Hope this helps.

@tgex0
Copy link
Contributor Author

tgex0 commented Aug 25, 2024

Thanks for the update. However, I like to have multiple line labels and really need a smaller "Row height" than is currently available to not have what I consider too much space between the rows. I found that allowing a smaller "Row height" (just by changing the lower limit in the UI) works for me.

@tgex0
Copy link
Contributor Author

tgex0 commented Aug 25, 2024

Nice! Thank you very much.

@tgex0
Copy link
Contributor Author

tgex0 commented Aug 25, 2024

@SuperDragonXD

Bug: App crashes when trying to access App Drawer settings

I've just tried the latest nightly (Lawnchair.Debug.14-dev.Nightly-CI_1283-192cb03.apk) which includes commit 192cb03 and it crashes when you try to open the App Drawer settings.
I've checked on two different phones (POCO X5 5G running stock HyperOS 1.0.5.0 and Xiaomi MI 8 running LineageOS 21).
I also built a fresh APK with the current 14-dev source with the same results.
Here is the log from the latest nightly:

Lawnchair (Debug) bug report 25 Aug 2024 18:02:46
version: 14.Dev.(#1283) (14000203)
commit: 192cb03
build.brand: Xiaomi
build.device: dipper
build.display: lineage_dipper-userdebug 14 AP2A.240805.005 89030f8c10
build.fingerprint: Xiaomi/dipper/dipper:8.1.0/OPM1.171019.011/V9.5.5.0.OEAMIFA:user/release-keys
build.hardware: qcom
build.id: AP2A.240805.005
build.manufacturer: Xiaomi
build.model: MI 8
build.security.level: 2024-08-05
build.product: dipper
build.type: userdebug
version.codename: REL
version.incremental: 89030f8c10
version.release: 14
version.sdk_int: 34
display.density_dpi: 440
isRecentsEnabled: false

error: Uncaught exception

java.lang.IllegalArgumentException: value range must be a multiple of step
	at app.lawnchair.ui.preferences.components.controls.SliderPreferenceKt.getSteps(SliderPreference.kt:144)
	at app.lawnchair.ui.preferences.components.controls.SliderPreferenceKt$SliderPreference$4.invoke(SliderPreference.kt:127)
	at app.lawnchair.ui.preferences.components.controls.SliderPreferenceKt$SliderPreference$4.invoke(SliderPreference.kt:121)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at app.lawnchair.ui.preferences.components.layout.PreferenceTemplateKt$PreferenceTemplate$1$3$3$1$2.invoke(PreferenceTemplate.kt:94)
	at app.lawnchair.ui.preferences.components.layout.PreferenceTemplateKt$PreferenceTemplate$1$3$3$1$2.invoke(PreferenceTemplate.kt:93)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:380)
	at app.lawnchair.ui.preferences.components.layout.PreferenceTemplateKt.PreferenceTemplate-vCe147k(PreferenceTemplate.kt:90)
	at app.lawnchair.ui.preferences.components.controls.SliderPreferenceKt.SliderPreference(SliderPreference.kt:89)
	at app.lawnchair.ui.preferences.destinations.AppDrawerPreferencesKt$AppDrawerPreferences$1$3.invoke(AppDrawerPreferences.kt:94)
	at app.lawnchair.ui.preferences.destinations.AppDrawerPreferencesKt$AppDrawerPreferences$1$3.invoke(AppDrawerPreferences.kt:87)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at app.lawnchair.ui.preferences.components.layout.DividerColumnKt.DividerColumn-zl7e28Q(DividerColumn.kt:145)
	at app.lawnchair.ui.preferences.components.layout.PreferenceGroupKt$PreferenceGroup$1$1.invoke(PreferenceGroup.kt:59)
	at app.lawnchair.ui.preferences.components.layout.PreferenceGroupKt$PreferenceGroup$1$1.invoke(PreferenceGroup.kt:57)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:126)
	at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:108)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:380)
	at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:105)
	at app.lawnchair.ui.preferences.components.layout.PreferenceGroupKt.PreferenceGroup-qKj4JfE(PreferenceGroup.kt:53)
	at app.lawnchair.ui.preferences.destinations.AppDrawerPreferencesKt$AppDrawerPreferences$1.invoke(AppDrawerPreferences.kt:87)
	at app.lawnchair.ui.preferences.destinations.AppDrawerPreferencesKt$AppDrawerPreferences$1.invoke(AppDrawerPreferences.kt:54)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at app.lawnchair.ui.preferences.components.layout.ScrollContainersKt$PreferenceColumn$1.invoke(ScrollContainers.kt:117)
	at app.lawnchair.ui.preferences.components.layout.ScrollContainersKt$PreferenceColumn$1.invoke(ScrollContainers.kt:36)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at app.lawnchair.ui.preferences.components.layout.NestedScrollStretchKt.NestedScrollStretch(NestedScrollStretch.kt:59)
	at app.lawnchair.ui.preferences.components.layout.ScrollContainersKt.PreferenceColumn(ScrollContainers.kt:34)
	at app.lawnchair.ui.preferences.components.layout.PreferenceLayoutKt$PreferenceLayout$1.invoke(PreferenceLayout.kt:70)
	at app.lawnchair.ui.preferences.components.layout.PreferenceLayoutKt$PreferenceLayout$1.invoke(PreferenceLayout.kt:69)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at app.lawnchair.ui.preferences.components.layout.PreferenceScaffoldKt$PreferenceScaffold$2.invoke(PreferenceScaffold.kt:54)
	at app.lawnchair.ui.preferences.components.layout.PreferenceScaffoldKt$PreferenceScaffold$2.invoke(PreferenceScaffold.kt:53)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:118)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:261)
	at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1$bodyContentPlaceables$1.invoke(Scaffold.kt:238)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:1017)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:493)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:109)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:97)
	at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3593)
	at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3520)
	at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:743)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:1122)
	at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3874)
	at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:649)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:635)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:516)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:488)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:479)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:463)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:895)
	at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1.invoke-0kLqBqw(Scaffold.kt:238)
	at androidx.compose.material3.ScaffoldKt$ScaffoldLayout$1$1.invoke(Scaffold.kt:140)
	at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:725)
	at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:135)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:316)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:315)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:503)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:502)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:258)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:113)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1775)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:40)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:696)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:672)
	at androidx.compose.foundation.layout.BoxMeasurePolicy.measure-3p2s80s(Box.kt:151)
	at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:135)
	at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:646)
	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:316)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:315)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:503)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:502)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:258)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:113)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1775)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:40)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:696)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:672)
	at androidx.compose.animation.AnimatedEnterExitMeasurePolicy.measure-3p2s80s(AnimatedVisibility.kt:812)
	at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:135)
	at androidx.compose.animation.EnterExitTransitionModifierNode.measure-3p2s80s(EnterExitTransition.kt:1173)
	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
	at androidx.compose.ui.graphics.BlockGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:578)
	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
	at androidx.compose.animation.AnimatedContentKt$AnimatedContent$6$1$1$1.invoke-3p2s80s(AnimatedContent.kt:781)
	at androidx.compose.animation.AnimatedContentKt$AnimatedContent$6$1$1$1.invoke(AnimatedContent.kt:780)
	at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(LayoutModifier.kt:294)
	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:188)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:316)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:315)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:503)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:502)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:258)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:113)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1775)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:40)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:696)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:672)
	at androidx.compose.animation.AnimatedContentMeasurePolicy.measure-3p2s80s(AnimatedContent.kt:837)
	at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:135)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:316)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasureBlock$1.invoke(LayoutNodeLayoutDelegate.kt:315)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2441)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:502)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:258)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:113)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1775)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:40)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:696)
	at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1221)
	at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default(LayoutNode.kt:1212)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:369)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:566)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.onlyRemeasureIfScheduled(MeasureAndLayoutDelegate.kt:660)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:686)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:693)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtree(MeasureAndLayoutDelegate.kt:649)
	at androidx.compose.ui.platform.AndroidComposeView.forceMeasureTheSubtree(AndroidComposeView.android.kt:1304)
	at androidx.compose.ui.node.Owner.forceMeasureTheSubtree$default(Owner.kt:263)
	at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:708)
	at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1221)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:367)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureOnly(MeasureAndLayoutDelegate.kt:622)
	at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureOnly(MeasureAndLayoutDelegate.kt:420)
	at androidx.compose.ui.platform.AndroidComposeView.onMeasure(AndroidComposeView.android.kt:1369)
	at android.view.View.measure(View.java:27866)
	at androidx.compose.ui.platform.AbstractComposeView.internalOnMeasure$ui_release(ComposeView.android.kt:309)
	at androidx.compose.ui.platform.AbstractComposeView.onMeasure(ComposeView.android.kt:296)
	at android.view.View.measure(View.java:27866)
	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7028)
	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
	at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)
	at android.view.View.measure(View.java:27866)
	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7028)
	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1608)
	at android.widget.LinearLayout.measureVertical(LinearLayout.java:878)
	at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
	at android.view.View.measure(View.java:27866)
	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7028)
	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
	at android.view.View.measure(View.java:27866)
	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7028)
	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1608)
	at android.widget.LinearLayout.measureVertical(LinearLayout.java:878)
	at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
	at android.view.View.measure(View.java:27866)
	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7028)
	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
	at com.android.internal.policy.DecorView.onMeasure(DecorView.java:768)
	at android.view.View.measure(View.java:27866)
	at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4486)
	at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3012)
	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3333)
	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2718)
	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9937)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1406)
	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1415)
	at android.view.Choreographer.doCallbacks(Choreographer.java:1015)
	at android.view.Choreographer.doFrame(Choreographer.java:945)
	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1389)
	at android.os.Handler.handleCallback(Handler.java:959)
	at android.os.Handler.dispatchMessage(Handler.java:100)
	at android.os.Looper.loopOnce(Looper.java:232)
	at android.os.Looper.loop(Looper.java:317)
	at android.app.ActivityThread.main(ActivityThread.java:8592)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878)```

@tgex0
Copy link
Contributor Author

tgex0 commented Aug 25, 2024

There's some floating point weirdness going on in the getSteps function in SliderPreference.kt.
It works fine if the starting value is 0.0F, 0.1F, 0.3F, 0.4F or 0.5F but 0.2F throws it off. On Line 144 of SliderPreference.kt, (start + step * steps) equals 1.4000001 instead of the expected 1.5. You could just change the starting value to something other than 0.2F but I guess the better option would be to fix the check in the getSteps function.

@SuperDragonXD
Copy link
Collaborator

I'd rather not work with floating points as of now, so I just updated the minimum value to 0.3F instead.

@tgex0
Copy link
Contributor Author

tgex0 commented Aug 25, 2024

I'll just leave this here in case you'd like to use it to fix the root of the problem (in SliderPreference.kt).
Otherwise, a change to any slider's range or step float value in the future could potentially cause a similar crash.

fun getSteps(valueRange: ClosedFloatingPointRange<Float>, step: Float): Int {
    if (step == 0f) return 0
    val start = valueRange.start.toBigDecimal()
    val end = valueRange.endInclusive.toBigDecimal()
    val test = (end - start) / step.toBigDecimal()
    val steps = test.toInt()
    require(test.compareTo(steps.toBigDecimal()) == 0) {
        "value range must be a multiple of step"
    }
    return steps - 1
}

I've tested it myself (in isolation and in a test build) and it seems pretty robust and works well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants