I am new to Android Development and I just wanted to implement a LazyColumn with some custom composable inside (while doing the Coursera Meta Android Development course). Unfortunately, every time I try to scroll the column list in the emulator the app stops. The same is true of the example "solution" provided by Coursera.
First I tried to implement the LazyColumn as specified by Coursera, that is:
I have a repository of elements of the data class Dish:
object DishRepository {
val dishes = listOf(
Dish(
1,
"Greek Salad",
"The famous greek salad of crispy lettuce, peppers, olives, our Chicago.",
12.99,
R.drawable.greeksalad
),
Dish(
2, etc etc
then I have a MenuDish composable:
@Composable
fun MenuDish(id: Int, dish: Dish) {
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
Image(painter = painterResource(id = dish.imageResource),
contentDescription = "Dish image",
modifier = Modifier.fillMaxWidth(),
contentScale = ContentScale.FillWidth)
Column (verticalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.padding(start = 10.dp, end = 10.dp)) {
Text(
text = dish.name,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(8.dp)
)
Text(
text = dish.description,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(8.dp)
)
}
}
}}
and in an appropriate composable I did this:
LazyColumn {
itemsIndexed(dishes) { _, dish ->
MenuDish( dish)
}
this crashes the app and produces the stack trace as below.
So I tried this:
LazyColumn {
items(5000) {
MenuDish( dish)
}
passing only one single dish (say No 1 or No 2 or any other number) from the repository – this worked perfectly without any issues at all.
then I tried
LazyColumn {
item{
MenuDish( dish1)
}
item{
MenuDish( dish2)
}
item{
MenuDish( dish3)
}
etc etc
this again crashed the app when I tried scrolling the list.
Finally I downloaded the Coursera solution (for anyone who can access – happy to send through email or whatever
which has the same issue – stopping when the list is scrolled.
I also tried creating my own project from scratch to avoid any issues of outdated libraries etc and writing the same code – the same problem appears – always with the same stack trace.
I’m using Android Studio Hedgehog 2023.1.1 Patch 2
EDIT:
After more experiments and looking at the stack trace, it seems that he problem is, in fact, caused by two specific images:
the only distinguishing feature of these is that they have dimensions larger than the others (but not size as one of the images that display correctly
has 6MB – but is 4928×3263)
they are:
3.7MB – 6589×4395 and
12MB – 8256×5504
Unfortunately changing the way the images are displayed (as far as I can see) that is setting modifier = Modifier.size(50.dp) removing the fillWidth and/or fillMaxWidth, changing to fillHeight etc does not help and those two images produce the same exeption.
StackTrace:
E FATAL EXCEPTION: main
Process: com.jan.testapp, PID: 7144
java.lang.RuntimeException: Canvas: trying to draw too large(181764096bytes) bitmap.
at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:266)
at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
at androidx.compose.ui.graphics.AndroidCanvas.drawImageRect-HPBpro0(AndroidCanvas.android.kt:271)
at androidx.compose.ui.graphics.drawscope.CanvasDrawScope.drawImage-AZ2fEMs(CanvasDrawScope.kt:263)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawImage-AZ2fEMs(Unknown Source:40)
at androidx.compose.ui.graphics.drawscope.DrawScope.drawImage-AZ2fEMs$default(DrawScope.kt:510)
at androidx.compose.ui.graphics.painter.BitmapPainter.onDraw(BitmapPainter.kt:93)
at androidx.compose.ui.graphics.painter.Painter.draw-x_KDEd0(Painter.kt:212)
at androidx.compose.ui.draw.PainterNode.draw(PainterModifier.kt:342)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:365)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:354)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:54)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:384)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:383)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2299)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:467)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:383)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:54)
at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:209)
at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:305)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:246)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:349)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:354)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:354)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:922)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:174)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:54)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:384)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:383)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2299)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:467)
2024-01-25 10:43:54.276 7144-7144 AndroidRuntime com.jan.testapp E at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:383)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:54)
at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:209)
at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:305)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:246)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:349)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:922)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:174)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:66)
at androidx.compose.foundation.DrawOverscrollModifier.draw(AndroidOverscroll.kt:79)
at androidx.compose.ui.node.BackwardsCompatNode.draw(BackwardsCompatNode.kt:349)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:365)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:354)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:54)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:384)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:383)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2299)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:467)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:383)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:54)
at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:209)
at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:305)
at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1138)
at android.view.View.draw(View.java:23892)
at android.view.View.updateDisplayListIfDirty(View.java:22756)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
at android.view.View.updateDisplayListIfDirty(View.java:22712)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
at android.view.View.updateDisplayListIfDirty(View.java:22712)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
at android.view.View.updateDisplayListIfDirty(View.java:22712)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4540)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4513)
at android.view.View.updateDisplayListIfDirty(View.java:22712)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:694)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:700)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:798)
2024-01-25 10:43:54.277 7144-7144 AndroidRuntime com.jan.testapp E at android.view.ViewRootImpl.draw(ViewRootImpl.java:4939)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4643)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3822)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2465)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9305)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1339)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:882)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
2
Answers
First, make sure you are importing the correct dependencies:
Then, try the following:
Try to move the two images that are too large from the
drawable
folder into thedrawable-xxhdpi
folder and report back if that solves the issue.The images contained in the
drawable
folder are interpreted to be medium resolutiondrawable-mdpi
. These images will be scaled on high resolution screen accordingly. Now, if you put a high-resultion image in there and want to display it on a high-resolution screen, the image will be scaled up even more, resulting in a too big image. This could be happening in your case.