Git Product home page Git Product logo

accompanist's Introduction

Accompanist logo

Accompanist is a group of libraries that aim to supplement Jetpack Compose with features that are commonly required by developers but not yet available.

Accompanist is a labs like environment for new Compose APIs. We use it to help fill known gaps in the Compose toolkit, experiment with new APIs and to gather insight into the development experience of developing a Compose library. The goal of these libraries is to upstream them into the official toolkit, at which point they will be deprecated and removed from Accompanist.

For more details like, why does this library exist? Why is it not part of AndroidX? Will you be releasing more libraries? Check out our Accompanist FAQ.

Compose versions

Each release outlines what version of the Compose UI libraries it depends on. We are currently releasing multiple versions of Accompanist for the different versions of Compose:

Compose 1.0 (1.0.x)Maven Central
Compose 1.1 (1.1.x)Maven Central
Compose UI 1.2 (1.2.x)Maven Central
Compose UI 1.3 (1.3.x)Maven Central

For stable versions of Compose, we use the latest stable version of the Compose compiler. For non-stable versions (alpha, beta, etc), we use the latest compiler at the time of release.

⚠️ Ensure you are using the Accompanist version that matches with your Compose UI version: If you upgrade Accompanist, it will upgrade your Compose libraries version via transitive dependencies.

Libraries

🍫 System UI Controller

A library that provides easy-to-use utilities for recoloring the Android system bars from Jetpack Compose.

🎨 AppCompat Theme Adapter

A library that enables the reuse of AppCompat XML themes for theming in Jetpack Compose.

📖 Pager

A library that provides utilities for building paginated layouts in Jetpack Compose, similar to Android's ViewPager.

📫 Permissions

A library that provides Android runtime permissions support for Jetpack Compose.

Placeholder

A library that provides easy-to-use modifiers for displaying a placeholder UI while content is loading.

🌊 Flow Layouts

A library that adds Flexbox-like layout components to Jetpack Compose.

🧭Navigation-Animation

A library which provides Compose Animation support for Jetpack Navigation Compose.

🧭🎨️ Navigation-Material

A library which provides Compose Material support, such as modal bottom sheets, for Jetpack Navigation Compose.

🖌️ Drawable Painter

A library which provides a way to use Android Drawables as Jetpack Compose Painters.

⬇️ Swipe to Refresh

A library that provides a layout implementing the swipe-to-refresh UX pattern, similar to Android's SwipeRefreshLayout.

🌏 Web

A wrapper around WebView for basic WebView support in Jetpack Compose.

📜 Adaptive

A library providing a collection of utilities for adaptive layouts.

📐 Insets (Deprecated)

See our Migration Guide for migrating to Insets in Compose.


Future?

Any of the features available in this group of libraries may become obsolete in the future, at which point they will (probably) become deprecated.

We will aim to provide a migration path (where possible), to whatever supersedes the functionality.

Snapshots

Snapshots of the current development version of Accompanist are available, which track the latest commit. See here for more information.


Why the name?

The library is all about adding some utilities around Compose. Music composing is done by a composer, and since this library is about supporting composition, the supporting role of an accompanist felt like a good name.

Contributions

Please contribute! We will gladly review any pull requests. Make sure to read the Contributing page first though.

License

Copyright 2020 The Android Open Source Project
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

accompanist's People

Contributors

chrisbanes avatar bentrengrove avatar JoseAlcerreca avatar andkulikov avatar alexvanyo avatar manuelvicnt avatar nickbutcher avatar fornewid avatar jossiwolf avatar probot-auto-merge[bot] avatar ianhanniballake avatar svenjacobs avatar sampengilly avatar arkon avatar jbw0033 avatar xiaozhikang0916 avatar chachako avatar Nthily avatar ch4rl3x avatar patrykmichalik avatar rlatapy-luna avatar ricknout avatar ln-12 avatar mxalbert1996 avatar yasincidem avatar NUmeroAndDev avatar OneFiveFour avatar CaptnBlubber avatar colintheshots avatar morrisseyai avatar

Stargazers

thebluepandabear avatar Swakresna Edityomurti avatar Katili Jiwo Adi Wiyono avatar Shashank Pandey avatar Jacob Rakidzich avatar Mariusz Tanski avatar Ersoy Filinte avatar  avatar Kader Tuna avatar  avatar Eko Yulianto avatar 施政 avatar Angel Anton avatar Al Bodelu avatar Abel Pascual avatar artorias avatar Qingwei Kong avatar adgvcxz avatar Tohka avatar 陈伟 avatar Gary avatar Adrian Ruiz avatar  avatar Bin avatar Joel  Muraguri avatar  avatar 노소래 avatar yangfengfandev avatar Marat Tursynbek avatar 梦远SAMA~ avatar Ar Razy Fathan Rabbani avatar  avatar Lyc avatar  avatar Elena Naumova avatar CuiBenguang avatar  avatar MandosBor avatar  avatar Coopsrc avatar Martynas Šustavičius avatar Steve Bedard avatar Frederico Gassen avatar HaniFakhouri avatar Leonardo Murça avatar Rogério Baron Júnior avatar Jessica Richardson avatar Hüseyin Aslan avatar Raana Yavari avatar  avatar Younes Lagmah avatar  avatar vulture2016 avatar Gerard jourdain Grégoire Charles  avatar Serhad Mert avatar  avatar Thomas Flad avatar Dmitrii Sobolev avatar ivio avatar Lime avatar Eugenio Cunha avatar Changyeon Seo avatar  avatar Viktor avatar  avatar hujiulong avatar yuki avatar hinnka avatar Atsushi USUI avatar ssiapp avatar OneStep avatar Heiko avatar Rickard Zettervall avatar Bruno Piovan avatar Yudistira Gita Ramadhan avatar Gabriel avatar Yassine Abou avatar Nauval Rizky avatar Muhammed Esad Cömert avatar MatrixNerd avatar İbrahim Ethem Şen avatar  avatar  avatar HuangPing avatar  avatar Rauan Kussembayev avatar Murat Tuğrul avatar  avatar Harrison Huang avatar  avatar Guille avatar  avatar Todayama_R avatar Omar El Hefny avatar DANIEL AZIZ avatar Kiran Prasad avatar Torey_Clark avatar Derek Fredrickson avatar Sadegh Khoshbayan avatar  avatar

Watchers

Ben Trengrove avatar Wayne May avatar Nick Butcher avatar  avatar Jose Alcérreca avatar Abhinav Kulshreshtha avatar James Cloos avatar  avatar Gaëtan Muller avatar Runrioter Wung avatar Bojana Dumeljic avatar Drew Heavner avatar John S. avatar hyl87 avatar Justin Hachemeister avatar Ali Shariat avatar Raghavendra Badaskar avatar smoonthsky avatar Maxim avatar xwhy avatar 吴上阿吉 avatar Alex Vanyo avatar  avatar Kostiantyn Yamshynskyi avatar Md. Shahriar Anwar avatar Yoshihiro Kobayashi avatar Johnny avatar Dhiman Dasgupta avatar Alessandro Caliaro avatar Dayan Ruben avatar Dylan avatar Abdalla Elnaggar avatar Mohamed avatar Ale Stamato avatar photoxor avatar Andrey Miroshnychenko avatar T avatar Anton Krutko avatar  avatar Doris Liu avatar Jerry Hanks Okafor avatar Yasin Çidem avatar Mehmet Ali Ocak avatar Hitesh Vishwas Sutar avatar Leo avatar Frederico Sisconetto Noce avatar  avatar Oscar Perez avatar Ivan avatar Chris avatar Andrea Ji avatar  avatar Md. Kofil Uddin avatar Jianyu Dong avatar  avatar  avatar houzhi avatar Bharath Venkatesan avatar lxb avatar Zakhar Rodionov avatar  avatar Matteo Somensi avatar @Morse  avatar Orlando Novas Rodriguez avatar  avatar Odin Asbjørnsen avatar Su avatar Jason Ozias avatar  avatar Richard French avatar  avatar Joji Martinez avatar  avatar Joshuwa Kellar avatar Raviteja avatar Stanislav avatar  avatar Tin P avatar  avatar  avatar  avatar  avatar  avatar

accompanist's Issues

Image not loading with fragment integration

Images are not getting loaded on Android 5.1.1 when you integrate Compose and fragments (inflate the XML layout using AndroidViewBinding). You can reproduce the issue on the Jetsnack sample app by adding a CoilImage on the ConversationContent (or in any other composable). CoilImage works fine for Android > 5.1

[Image Loading] Display something better when in Preview

Currently CoilImage, PicassoImage, and GlideImage all have different issues when used in @Preview. We should do something better.

  • Make sure that using each of these functions does not crash the preview
  • Think about adding a placeholder parameter to be displayed when in preview.

[Idea] New Pager library

This would be take the Pager component from Jetcaster, and fix the issues around touch handling, flinging, etc.

It may even be a whole new implementation wrapping LazyRow.

0.3.0 crashing against 1.0.0-alpha04 with No static method CoilImage

Hi, I am using the latest 0.3.0 of this library with Jetpack Compose 1.0.0-alpha03. I am using the CoilImage function. I get the following crash when I run the application. Code flow does reach the actual CoilImage function call itself (the issue is deeper).

2020-10-01 14:25:55.082 15001-15001/app.itsyour.itsyournutrition E/AndroidRuntime: FATAL EXCEPTION: main Process: app.itsyour.itsyournutrition, PID: 15001 java.lang.NoSuchMethodError: No static method CoilImage(Ljava/lang/Object;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;Landroidx/compose/ui/graphics/ColorFilter;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V in class Ldev/chrisbanes/accompanist/coil/CoilKt; or its super classes (declaration of 'dev.chrisbanes.accompanist.coil.CoilKt' appears in /data/app/~~hZq07ZuSRRmAHYpqOVfFBw==/app.itsyour.itsyournutrition-kT_xgZ6y7k-HH0onnTZ1Pg==/base.apk!classes13.dex) at app.itsyour.itsyournutrition.app.ui.NetworkImageKt.NetworkImage-DCd5uiY(NetworkImage.kt:26) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2$1$1.invoke(CuisineSetting.kt:71) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2$1$1.invoke(Unknown Source:13) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:153) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.foundation.layout.BoxKt$Box$boxChildren$1.invoke(Box.kt:54) at androidx.compose.foundation.layout.BoxKt$Box$boxChildren$1.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:144) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.ui.LayoutKt.Layout(Layout.kt:677) at androidx.compose.foundation.layout.BoxKt.Box(Box.kt:56) at androidx.compose.foundation.layout.BoxKt.Stack(Box.kt:126) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2.invoke(CuisineSetting.kt:70) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:144) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175) at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:107) at androidx.compose.material.SurfaceKt$Surface$1.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:144) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.ui.LayoutKt.Layout(Layout.kt:677) at androidx.compose.material.SurfaceKt.SurfaceLayout(Surface.kt:129) at androidx.compose.material.SurfaceKt.Surface-biUpMIw(Surface.kt:97) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt.CuisineChip(CuisineSetting.kt:64) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt.CuisineSetting(CuisineSetting.kt:30) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1$3.invoke(Screen.kt:41) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1$3.invoke(Unknown Source:13) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:153) at androidx.compose.runtime.internal.ComposableLambda$invoke$1.invoke(ComposableLambda.kt:164) at androidx.compose.runtime.internal.ComposableLambda$invoke$1.invoke(Unknown Source:10) at androidx.compose.runtime.RecomposeScope.compose(Composer.kt:257) at androidx.compose.runtime.Composer.recomposeToGroupEnd(Composer.kt:1560) at androidx.compose.runtime.Composer.skipToGroupEnd(Composer.kt:1784) at androidx.compose.material.ScaffoldKt.Scaffold-tiGujGI(Scaffold.kt:241) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1.invoke(Screen.kt:33) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1.invoke(Unknown Source:10) 2020-10-01 14:25:55.082 15001-15001/app.itsyour.itsyournutrition E/AndroidRuntime: at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:144) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.runtime.RecomposeScope.compose(Composer.kt:257) at androidx.compose.runtime.Composer.recomposeToGroupEnd(Composer.kt:1560) at androidx.compose.runtime.Composer.skipToGroupEnd(Composer.kt:1784) at androidx.compose.material.SurfaceKt.Surface-biUpMIw(Surface.kt:97) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt.ProfileScreen(Screen.kt:32) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$2.invoke(Unknown Source:6) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$2.invoke(Unknown Source:10) at androidx.compose.runtime.RecomposeScope.compose(Composer.kt:257) at androidx.compose.runtime.Composer.recomposeToGroupEnd(Composer.kt:1560) at androidx.compose.runtime.Composer.skipCurrentGroup(Composer.kt:1763) at androidx.compose.runtime.Composer.recompose(Composer.kt:1886) at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:259) at androidx.compose.runtime.Recomposer.access$performRecompose(Unknown Source:0) at androidx.compose.runtime.Recomposer$recomposeAndApplyChanges$2$2.invoke(Recomposer.kt:199) at androidx.compose.runtime.Recomposer$recomposeAndApplyChanges$2$2.invoke(Unknown Source:7) at androidx.compose.runtime.dispatch.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.kt:34) at androidx.compose.runtime.dispatch.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.kt:111) at androidx.compose.runtime.dispatch.AndroidUiDispatcher.access$performFrameDispatch(Unknown Source:0) at androidx.compose.runtime.dispatch.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.kt:71) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:970) at android.view.Choreographer.doCallbacks(Choreographer.java:796) at android.view.Choreographer.doFrame(Choreographer.java:727) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

If I drop the version down to 0.2.0 then I get this crash when the CoilImage function is reached in program flow (the application doesn't crash on startup but instead when the method is actually called).

2020-10-01 14:17:32.215 14141-14141/app.itsyour.itsyournutrition E/AndroidRuntime: FATAL EXCEPTION: main Process: app.itsyour.itsyournutrition, PID: 14141 java.lang.NoSuchMethodError: No static method CoilImage(Ljava/lang/Object;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;Landroidx/compose/ui/graphics/ColorFilter;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V in class Ldev/chrisbanes/accompanist/coil/CoilKt; or its super classes (declaration of 'dev.chrisbanes.accompanist.coil.CoilKt' appears in /data/app/~~MMh01prcAq4RIusDjlQzkg==/app.itsyour.itsyournutrition-EN1RCfCxNy8nkVBGKyBCDg==/base.apk!classes13.dex) at app.itsyour.itsyournutrition.app.ui.NetworkImageKt.NetworkImage-DCd5uiY(NetworkImage.kt:26) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2$1$1.invoke(CuisineSetting.kt:71) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2$1$1.invoke(Unknown Source:13) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:151) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.foundation.layout.StackKt$Stack$stackChildren$1.invoke(Stack.kt:54) at androidx.compose.foundation.layout.StackKt$Stack$stackChildren$1.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.ui.LayoutKt.Layout(Layout.kt:675) at androidx.compose.foundation.layout.StackKt.Stack(Stack.kt:56) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2.invoke(CuisineSetting.kt:70) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt$CuisineChip$2.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175) at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:107) at androidx.compose.material.SurfaceKt$Surface$1.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142) at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.ui.LayoutKt.Layout(Layout.kt:675) at androidx.compose.material.SurfaceKt.SurfaceLayout(Surface.kt:129) at androidx.compose.material.SurfaceKt.Surface-biUpMIw(Surface.kt:97) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt.CuisineChip(CuisineSetting.kt:64) at app.itsyour.itsyournutrition.feature.profile.ui.settings.CuisineSettingKt.CuisineSetting(CuisineSetting.kt:30) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1$3.invoke(Screen.kt:41) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1$3.invoke(Unknown Source:13) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:151) at androidx.compose.runtime.internal.ComposableLambda$invoke$1.invoke(ComposableLambda.kt:160) at androidx.compose.runtime.internal.ComposableLambda$invoke$1.invoke(Unknown Source:10) at androidx.compose.runtime.RecomposeScope.compose(Composer.kt:257) at androidx.compose.runtime.Composer.recomposeToGroupEnd(Composer.kt:1556) at androidx.compose.runtime.Composer.skipToGroupEnd(Composer.kt:1776) at androidx.compose.material.ScaffoldKt.Scaffold-tiGujGI(Scaffold.kt:241) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1.invoke(Screen.kt:33) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$1.invoke(Unknown Source:10) at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142) 2020-10-01 14:17:32.216 14141-14141/app.itsyour.itsyournutrition E/AndroidRuntime: at androidx.compose.runtime.internal.ComposableLambda.invoke(Unknown Source:10) at androidx.compose.runtime.RecomposeScope.compose(Composer.kt:257) at androidx.compose.runtime.Composer.recomposeToGroupEnd(Composer.kt:1556) at androidx.compose.runtime.Composer.skipToGroupEnd(Composer.kt:1776) at androidx.compose.material.SurfaceKt.Surface-biUpMIw(Surface.kt:97) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt.ProfileScreen(Screen.kt:32) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$2.invoke(Unknown Source:6) at app.itsyour.itsyournutrition.feature.profile.ui.ScreenKt$ProfileScreen$2.invoke(Unknown Source:10) at androidx.compose.runtime.RecomposeScope.compose(Composer.kt:257) at androidx.compose.runtime.Composer.recomposeToGroupEnd(Composer.kt:1556) at androidx.compose.runtime.Composer.skipCurrentGroup(Composer.kt:1755) at androidx.compose.runtime.Composer.recompose(Composer.kt:1878) at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:259) at androidx.compose.runtime.Recomposer.access$performRecompose(Unknown Source:0) at androidx.compose.runtime.Recomposer$recomposeAndApplyChanges$2$2.invoke(Recomposer.kt:199) at androidx.compose.runtime.Recomposer$recomposeAndApplyChanges$2$2.invoke(Unknown Source:7) at androidx.compose.runtime.dispatch.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.kt:34) at androidx.compose.runtime.dispatch.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.kt:111) at androidx.compose.runtime.dispatch.AndroidUiDispatcher.access$performFrameDispatch(Unknown Source:0) at androidx.compose.runtime.dispatch.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.kt:71) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:970) at android.view.Choreographer.doCallbacks(Choreographer.java:796) at android.view.Choreographer.doFrame(Choreographer.java:727) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Avoid Auto-Rotation Behavior (coil-image)

Hey, I have a common workflow where a user takes a picture, and then that picture is used as the avatar photo for their profile. Currently, if I take a selfie with the phone positioned vertically the image is automatically rotated. The component I'm using for the avatar is as follows:

@Composable
fun ImageAvatar(bitmap: Bitmap, onClick: (() -> Unit)? = null) {
    var modifier = Modifier
        .preferredSize(70.dp)
        .clip(CircleShape)
        .background(backgroundSecondary())
        .border(BorderStroke(1.dp, backgroundPrimary()), shape = CircleShape)

    onClick?.let { clickListener ->
        modifier = modifier.clickable(onClick = clickListener)
    }

    Box(modifier = modifier, alignment = Alignment.Center) {
        CoilImage(
            data = bitmap,
            contentScale = ContentScale.Crop,
            requestBuilder = {
                transformations(CircleCropTransformation())
            },
            modifier = Modifier.preferredSize(70.dp)
        )
    }
}

Is there a way to avoid automatic rotation behavior?

`CoilImage(...)` and Recomposition

I have a usecase where I have a grid of images (loaded over network) and when I click on an image I show a new screen with that that image loaded again in a larger container with some extra metadata. I am having issues updating the composable with a new image url, sometimes it will show the old image.

Here is gif of the issue:
coil_image_issue_smaller

Basically when I click on the first image it loads and shows correctly, but then when I click on other cells in the grid, it will show the image of the cell I previously clicked.

Anything I am doing wrong? It's recomposing and updating the data passed in, but not always showing the new image.

App crashes when using GlideImage with error after onResume

When using GlideImage with no network or with invalid URL the error composable function is shown correctly,
but after switching to another app or closing the screen and returning, the app crashes.

The Code:

    GlideImage(
        data = "",
        contentDescription = "",
        modifier = modifier,
        loading = {
            Box(Modifier.matchParentSize()) {
                CircularProgressIndicator(Modifier.align(Alignment.Center))
            }
        },
        error = {
            Image(
                imageVector = vectorResource(R.drawable.ic_gray_user),
                contentDescription = ""
            )
        },
        requestBuilder = {
            val options = RequestOptions()
            options.circleCrop()
            apply(options)
        },
    )

The Log

021-02-08 14:22:55.870 14936-14936/com.linguistic.linguistic W/Glide: Load failed for null with size [240x240]
    class com.bumptech.glide.load.engine.GlideException: Failed to load resource
    There were 3 causes:
    java.io.FileNotFoundException(/null: open failed: ENOENT (No such file or directory))
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail
      Cause (1 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, LOCAL
    There was 1 cause:
    java.io.FileNotFoundException(/null: open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail
        Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetch failed
    There was 1 cause:
    java.io.FileNotFoundException(/null: open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail
          Cause (1 of 1): class java.io.FileNotFoundException: /null: open failed: ENOENT (No such file or directory)
      Cause (2 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class android.os.ParcelFileDescriptor, LOCAL
    There was 1 cause:
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail
        Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetch failed
    There was 1 cause:
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail
          Cause (1 of 1): class java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
      Cause (3 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class android.content.res.AssetFileDescriptor, LOCAL
    There was 1 cause:
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail
        Cause (1 of 1): class java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
2021-02-08 14:22:55.870 22234-22234/? D/KeyguardUpdateMonitor: sendKeyguardBouncerChanged(false)
2021-02-08 14:22:55.870 22234-22288/? D/KeyguardUpdateMonitor: faceRunningState: 0
2021-02-08 14:22:55.870 14936-14936/com.linguistic.linguistic I/Glide: Root cause (1 of 3)
    java.io.FileNotFoundException: /null: open failed: ENOENT (No such file or directory)
        at libcore.io.IoBridge.open(IoBridge.java:496)
        at java.io.FileInputStream.<init>(FileInputStream.java:159)
        at java.io.FileInputStream.<init>(FileInputStream.java:115)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1204)
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:74)
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:50)
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:13)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
     Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
        at libcore.io.Linux.open(Native Method)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
        at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
        at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
        at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7725)
        at libcore.io.IoBridge.open(IoBridge.java:482)
        at java.io.FileInputStream.<init>(FileInputStream.java:159) 
        at java.io.FileInputStream.<init>(FileInputStream.java:115) 
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1204) 
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:74) 
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:50) 
        at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:13) 
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44) 
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100) 
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70) 
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63) 
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310) 
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279) 
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:919) 
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393) 
2021-02-08 14:22:55.870 14936-14936/com.linguistic.linguistic I/Glide: Root cause (2 of 3)
    java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
        at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
        at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1517)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1439)
        at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:20)
        at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:12)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
        at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
        at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
2021-02-08 14:22:55.871 3282-13885/? D/Launcher.TouchInteractionService: onSystemUiStateChanged: stateFlags = 0
2021-02-08 14:22:55.871 3282-3282/? D/Launcher.TouchInteractionService: onSystemUiFlagsChanged: mIsUserUnlocked = true
2021-02-08 14:22:55.871 14936-14936/com.linguistic.linguistic I/Glide: Root cause (3 of 3)
    java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
        at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
        at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1517)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1439)
        at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:20)
        at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:11)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
        at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
        at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
        at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
        at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
2021-02-08 14:22:55.871 22234-22234/? D/KeyguardViewMediator: adjustStatusBarLocked: mShowing=false mOccluded=false isSecure=true force=false --> flags=0x0
2021-02-08 14:22:55.871 14936-14936/com.linguistic.linguistic D/AndroidRuntime: Shutting down VM
    
    
    --------- beginning of crash
2021-02-08 14:22:55.873 14936-14936/com.linguistic.linguistic E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.linguistic.linguistic, PID: 14936
    com.bumptech.glide.load.engine.CallbackException: Unexpected exception thrown by non-Glide code
        at com.bumptech.glide.load.engine.EngineJob.callCallbackOnLoadFailed(EngineJob.java:174)
        at com.bumptech.glide.load.engine.EngineJob$CallLoadFailed.run(EngineJob.java:398)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:228)
        at android.app.ActivityThread.main(ActivityThread.java:7826)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:981)
     Caused by: java.lang.IllegalStateException: Already resumed, but proposed with update Error(painter=null, throwable=com.bumptech.glide.load.engine.GlideException: Failed to load resource
    There were 3 causes:
    java.io.FileNotFoundException(/null: open failed: ENOENT (No such file or directory))
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
    java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
     call GlideException#logRootCauses(String) for more detail)
        at kotlinx.coroutines.CancellableContinuationImpl.alreadyResumedError(CancellableContinuationImpl.kt:447)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:412)
        at kotlinx.coroutines.CancellableContinuationImpl.resume(CancellableContinuationImpl.kt:296)
        at dev.chrisbanes.accompanist.glide.GlideImage__GlideImageKt$execute$2$target$1.onLoadFailed(GlideImage.kt:229)
        at com.bumptech.glide.request.SingleRequest.setErrorPlaceholder(SingleRequest.java:425)
        at com.bumptech.glide.request.SingleRequest.onLoadFailed(SingleRequest.java:683)
        at com.bumptech.glide.request.SingleRequest.onLoadFailed(SingleRequest.java:643)
        at com.bumptech.glide.load.engine.EngineJob.callCallbackOnLoadFailed(EngineJob.java:172)
        	... 8 more

[Glide] Compose version 1.0.0-beta01 : java.lang.NoClassDefFoundError

When bumping up to the beta of compose that came out yesterday, GlideImage breaks the app.
Stacktrace:

  Process: <package_name>, PID: 8990
  java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/compose/ui/platform/AndroidAmbientsKt;
      at dev.chrisbanes.accompanist.glide.GlideImageDefaults.defaultRequestManager(GlideImage.kt:77)
      at dev.chrisbanes.accompanist.glide.GlideImage__GlideImageKt.GlideImage(GlideImage.kt:189)
      at dev.chrisbanes.accompanist.glide.GlideImage.GlideImage(GlideImage.kt:1)
     ...

Versions:

  • kotlin version: 1.4.30
  • compose 1.0.0-beta01
dependencies {

    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    implementation "androidx.compose.runtime:runtime:$compose_version"
    implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
    implementation "androidx.activity:activity-compose:1.3.0-alpha03"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'
    implementation 'androidx.room:room-runtime:2.2.6'
    implementation "androidx.compose.material:material-icons-extended:$compose_version"
    //noinspection GradleDynamicVersion
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

    // Room dependency
    def room_version = "2.2.6"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"

    // logging
    implementation 'com.jakewharton.timber:timber:4.7.1'

    // serializing
    implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1'

    // coroutines for getting off the UI thread
    def coroutines = "1.4.2"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"

    implementation "dev.chrisbanes.accompanist:accompanist-glide:0.5.1"

    // navigation
    // https://maven.google.com/web/index.html?q=androidx.nav#androidx.navigation:navigation-compose
    implementation "androidx.navigation:navigation-compose:1.0.0-alpha08"
}

Images are not exposed when the combination of AndroidView + FrameLayout + Fragment

When using fragments in accompanist's image loader and Composable, the behavior is incorrect at the first display.

Condition

  1. AndroidView + FrameLayout + Fragment combination
  2. Use accompanist's image loader inside Fragment

If you touch the Composable View, it is exposed.

Sample : https://github.com/Pluu/MaybeComposeBug

Sorry. It is not clear if it is a Compose issue, but only accompanist works differently, so I registered the issue here.

Add docs to undocumented code

According to Dokka:

Undocumented: dev.***.accompanist.coil/CoilImageConstants/ (androidJvm)
Undocumented: dev.***.accompanist.glide/GlideImageConstants/ (androidJvm)
Undocumented: dev.***.accompanist.imageloading/AndroidDrawablePainter/intrinsicSize/#/ (androidJvm)
Undocumented: dev.***.accompanist.imageloading/DataSource/ (androidJvm)
Undocumented: dev.***.accompanist.imageloading/ImageLoadingColorMatrix/saturationFraction/#/ (androidJvm)
Undocumented: dev.***.accompanist.imageloading/ImageLoadingColorMatrix/alphaFraction/#/ (androidJvm)
Undocumented: dev.***.accompanist.imageloading/ImageLoadingColorMatrix/brightnessFraction/#/ (androidJvm)

[Insets] How to use navigationBarsWithImePadding with Column verticalScroll?

Hello!

What is the best way to handle Column verticalScroll and navigationBarsWithImePadding?

I have layout like this:

When keyboard is shown it looks like this:

What I want to achieve (automatically scroll to given or focused composable when IME is shown) :

I was trying to play with scrollState.smoothScrollTo but without any reliable success :(. @chrisbanes do you have any recommendations or best ways of doing so?

Code:

class ExampleFragment: Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = ComposeView(requireContext()).apply {
        layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )

        val windowInsets = ViewWindowInsetObserver(this).start(consumeWindowInsets = false)

        setContent {
            Providers(
                LocalWindowInsets provides windowInsets
            ) {

                val scrollState = rememberScrollState()
                var textValue = remember { TextFieldValue() }

                Column(
                    modifier = Modifier.fillMaxSize(1F)
                        .statusBarsPadding()
                        .navigationBarsWithImePadding()
                        .verticalScroll(scrollState)
                        .padding(horizontal = 16.dp),
                    verticalArrangement = Arrangement.Top,
                ) {

                    Text(
                        text = "Hi there ❤",
                        fontSize = 46.sp,
                        style = TextStyle(
                            fontWeight = FontWeight.Bold,
                            textAlign = TextAlign.Center
                        ),
                        modifier = Modifier.fillMaxWidth(1F)
                    )

                    Spacer(modifier = Modifier.height(250.dp))

                    Text(
                        text = "More content",
                        fontSize = 20.sp,
                        style = TextStyle(
                            fontWeight = FontWeight.Bold,
                            textAlign = TextAlign.Center
                        ),
                        modifier = Modifier.fillMaxWidth(1F)
                    )

                    Text(
                        text = "More content #2",
                        fontSize = 20.sp,
                        style = TextStyle(
                            fontWeight = FontWeight.Bold,
                            textAlign = TextAlign.Center
                        ),
                        modifier = Modifier.fillMaxWidth(1F)
                    )

                    TextField(value = textValue, onValueChange = { textValue = it })
                }
            }
        }
    }
}

Add @Composable placeholder for errors

Something like:
error: @Composable ((ErrorResult) -> Unit)? = null

The reason is that you might be needed to display a custom placeholder if the load fails. The might not be a regular image as you might be needed to use some logic there (showing differect vectors assets, drawing checkmarks etc).

RoundedCornerShape on CoilImage affects only 2 bottom corners

I use CoilImage like this

CoilImageWithCrossfade(
          data = it,
          getFailurePainter = { ColorPainter(Color.Red) }
          contentScale = ContentScale.FillWidth,
          modifier = Modifier.clip(RoundedCornerShape(10.dp)).fillMaxWidth().padding(top = 8.dp)
)

And result is the following:
Screenshot_1600011190

The top corners are not affected. I tried the same thing on the Box composable and it works so it is not a compose issue. It also works with CircleShape clipping so I guess it is some issue with RoundedCornerShape clipping for images. Does this needs a fix or am I doing something wrong?

Integrate screenshot testing

Currently the testing is mostly functional, rather than looking at how the content is displayed. We should look at screenshot testing to make sure the visuals are consistent.

An example issue which we would have caught is #118

image not loading

Images are not getting loading in the new project, but it's working fine in JetSnack. Tried building using a new project as well.
Cross verified appropriate library versions as well.

Accompanist: 0.2.0
Compose: 1.0.0-alpha01
Kotlin: 1.4.0

[Help] How to use asFile() request Builder

I am trying to Accomplish Something Like this:

Load Image from a URL asFile then copy that file for later Use and and also load same Image.

If I do following using Drawable the image obtaines as File is of Low Res than original.

Glide
            .with(imgView)
            .asFile()
            .load(imgUri)
            .placeholder(R.drawable.ic_song_placeholder)
            .error(R.drawable.ic_musicplaceholder)
            .listener(object:RequestListener<File>{
                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: Target<File>?,
                    isFirstResource: Boolean
                ): Boolean {
                    log("Glide","LoadFailed")
                    return false
                }

                override fun onResourceReady(
                    resource: File?,
                    model: Any?,
                    target: Target<File>?,
                    dataSource: DataSource?,
                    isFirstResource: Boolean
                ): Boolean {
                    CoroutineScope(Dispatchers.Main).launch {
                            try {
                                val file = File(/*File Path*/)
                                resource?.copyTo(file)
                                Glide.with(imgView)
                                    .load(file)
                                    .placeholder(R.drawable.ic_song_placeholder)
                                    .into(imgView)
                            } catch (e: IOException) {
                                e.printStackTrace()
                            }
                    }
                     return false
                }
            }).submit()
        }

Desktop Compose support

Checking just in case there's any plans to create version that works with new Compose for Desktop release (or has this dependency on running on Android)?

CoilImage: ImageState is Empty (briefly) before the image loads.

When using the "content version" of the CoilImage composable, it is composed in the "empty" state briefly before the request starts (and it then gets recomposed in the "loading" state). This could cause a brief "flash" of the empty state, if the device is slow. I haven't seen it on a physical device, but if you add a log message in the content composable for the Empty state, you will see it. One way that I HAVE been able to see it, is to create a @Preview for the below composable, and then in Android Studio click the "Deploy Preview" button to deploy the preview to an emulator. When the preview app loads on the emulator, you can see the brief flash of the Empty State before the Loading state. For example:

@Composable
fun MyImage() {
    CoilImage(
        data = "https://picsum.photos/300/300",
    ) { imageState ->
        when (imageState) {
            is ImageLoadState.Success -> {
                MaterialLoadingImage(
                    result = imageState,
                    fadeInEnabled = true,
                    fadeInDurationMs = 600,
                )
            }
            is ImageLoadState.Error -> /* TODO */
            ImageLoadState.Loading -> Text("Loading...")
            ImageLoadState.Empty -> {
                  Log.d(TAG, "COIL IMAGE IS EMPTY")
                  Text("⚠️ EMPTY! ⚠️")
            }
        }
    }
}

When the MyImage composable is called the UI will go through the following states:

  1. ⚠️ EMPTY! ⚠️ (You won't typically see this on a device, but if you check the LogCat, you will find the "COIL IMAGE IS EMPTY" message logged there).
  2. Loading...
  3. image

It seems like it should go directly to the "Loading" state, and then to the Success (show the image) state, and skip the Empty state all together in this case.

Update needed for Compose alpha02?

Jetpack Compose alpha02 release includes note that seems to indicate that libraries will also need to be updated. If I try to use with "0.2.0 version of this library (using CoilImage in particular) I'm getting following crash

09-03 22:20:31.200 24543 24543 E AndroidRuntime: java.lang.NoSuchMethodError: No static method CoilImage(Ljava/lang/Object;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;Landroidx/compose/ui/graphics/ColorFilter;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V in class Ldev/chrisbanes/accompanist/coil/CoilKt; or its super classes (declaration of 'dev.chrisbanes.accompanist.coil.CoilKt' appears in /data/app/com.surrus.peopleinspace-2AZqMvFbdwYEpJUqGU1nHA==/base.apk)

White background colour

When the image is loaded (ImageLoadState.Success clause), the background appears in a white colour for about a second before the image is set. This happens although the background is set through the modifier to another colour.

To better reproduce you can set your device to dark mode and the background of the CoilImage to black via modifier.

This issue started appearing in version 0.6.0 and not before.

(On this note, I also wonder why there is this delay of about one second. Why isn't the image shown directly after it is loaded?)

CoilImage cannot display heif/heic images

When trying to display a heif/heic image via CoilImage using a remote url (example https://blink-content.s3.amazonaws.com/116ecc2a-4069-4365-afbf-ebb94ddb8d6b.heic), the image is not displayed and an error appears in the console:

E/HeifDecoderImpl: getSize: not supported!

The code that throws is likely here https://android.googlesource.com/platform/frameworks/av/+/android-8.1.0_r1/media/libheif/HeifDecoderImpl.cpp#258

Is there a way to use CoilImage such that heif decoding works as expected?

API update proposal

With the recent update we have 3 callback for each situation, such as:

  • Image is loading
  • Image is loaded
  • Image has failed to load.

We also have an internal sealed class RequestResult which represents the state of the loader. When the image is loading, the internal code uses null instead.

My suggestion is:

  • Make it public and rename to something like CoilState or CoilImage.
  • Move all the children classes inside parent for more code clarity, rename it to Success and Fail.
  • Add third state, object Loading: CoilState(), and use it instead of nulls, in a similar way Compose does for a lot of components, for example Modifier.
  • Move nullable image property from sealed class to success state, and make it not null.
  • Add a single trailing lambda for all the states, e.g. content: @Composable (CoilState) -> Unit. This will allow to use syntax like CoilImage(url){ it: CoilState -> } with when expression inside – it's more easy and consistent rather than using 3 lambdas.
  • Add an overload with the lambdas for other cases.

It'd be great to see CoilImage() as a state managing function, completely without rendering logic. Overloads with the current functionality may still be available as well.

It'd be interesting to hear more opinions from the community as well.

[Help] How to use asFile() ?

I am trying to Accomplish Something Like this:

Load Image from a URL asFile then copy that file for later Use and and also load same Image.

If I do following using Drawable the image obtaines as File is of Low Res than original.

Glide
            .with(imgView)
            .asFile()
            .load(imgUri)
            .placeholder(R.drawable.ic_song_placeholder)
            .error(R.drawable.ic_musicplaceholder)
            .listener(object:RequestListener<File>{
                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: Target<File>?,
                    isFirstResource: Boolean
                ): Boolean {
                    log("Glide","LoadFailed")
                    return false
                }

                override fun onResourceReady(
                    resource: File?,
                    model: Any?,
                    target: Target<File>?,
                    dataSource: DataSource?,
                    isFirstResource: Boolean
                ): Boolean {
                    CoroutineScope(Dispatchers.Main).launch {
                            try {
                                val file = File(/*File Path*/)
                                resource?.copyTo(file)
                                Glide.with(imgView)
                                    .load(file)
                                    .placeholder(R.drawable.ic_song_placeholder)
                                    .into(imgView)
                            } catch (e: IOException) {
                                e.printStackTrace()
                            }
                    }
                     return false
                }
            }).submit()
        }

No Such Field Error

Hiya i am getting the follow error when using CoilImage

java.lang.NoSuchFieldError: No field Companion of type Landroidx/compose/runtime/SlotTable$Companion; in class Landroidx/compose/runtime/SlotTable; or its superclasses (declaration of 'androidx.compose.runtime.SlotTable' appears in ..

i tried using Alpha05, Alpha06 and Alpha07 compose version along with the latest
0.3.3.1 of accompanist

Loading thumbnails for videos in device gallery

Hi, first thank you for this great library. I use it for displaying images loaded via network as well as for pictures of the device gallery.

Now I want to display thumbnails of videos of the device gallery. To do so, I fetch the list of the video-Uri, and was thinking to pass that uri to CoilImage like so:

CoilImage(
    data = assetUri,
    contentDescription = null,
    contentScale = ContentScale.Crop,
)

This obviously does not work and no image is displayed. So I use a utility method to fetch a thumbnail bitmap of the uri and pass that bitmap to CoilImage, like so:

CoilImage(
    data = assetUri.thumbnailFromVideoAt(context, 0L)!!,
    contentDescription = null,
    contentScale = ContentScale.Crop,
)

with

fun Uri.thumbnailFromVideoAt(context: Context, timeMs: Long): Bitmap? {
    val retriever = MediaMetadataRetriever()
    retriever.setDataSource(context, this)
    retriever.getFrameAtTime(timeMs * 1000)
}

This works, but it fetches the bitmap on the main thread and thus my image grid is very laggy.

I was wondering if there was a better solution. I'm currently looking how to use directly ImageLoad.

Thank you for your help.

Cannot resolve snapshots

I followed your instructions on how to use the latest snapshots but was unsuccessful. My project gradle file includes the following:

repositories {
    google()
    mavenCentral()
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}

I then added these dependencies:

dependencies {
    classpath 'dev.chrisbanes.accompanist:accompanist-coil:0.6.2-SNAPSHOT'
    classpath 'dev.chrisbanes.accompanist:accompanist-imageloading-core:0.6.2-SNAPSHOT'
    classpath 'dev.chrisbanes.accompanist:accompanist-insets:0.6.2-SNAPSHOT'
    classpath 'dev.chrisbanes.accompanist:accompanist-mdc-theme:0.1.6.ui-6602655-SNAPSHOT'
}

This results in the error of:

Could not resolve dev.chrisbanes.accompanist:accompanist-coil:0.6.2-SNAPSHOT.

I then attempted to move the dependencies to the app's gradle file and used this:

dependencies {
    implementation 'dev.chrisbanes.accompanist:accompanist-coil:0.6.2-SNAPSHOT'
    implementation 'dev.chrisbanes.accompanist:accompanist-imageloading-core:0.6.2-SNAPSHOT'
    implementation 'dev.chrisbanes.accompanist:accompanist-insets:0.6.2-SNAPSHOT'
    implementation 'dev.chrisbanes.accompanist:accompanist-mdc-theme:0.1.6.ui-6602655-SNAPSHOT'
}

This results in the errors:

Failed to resolve: dev.chrisbanes.accompanist:accompanist-imageloading-core:0.6.2-SNAPSHOT
Failed to resolve: dev.chrisbanes.accompanist:accompanist-insets:0.6.2-SNAPSHOT
Failed to resolve: dev.chrisbanes.accompanist:accompanist-coil:0.6.2-SNAPSHOT

Those snapshots do in fact exist at the locations specified, so I have no idea why they can't be found.

Personally, I find it a shame that Google's Android team has referenced this library as their main library for handling images. Like WTF?? I get it that Compose is still in beta, but seriously, to release a beta with zero native support for images for Android is just plain idiotic.

CoilImageWithCrossfade scale animation issue

Case:
Using CoilImageWithCrossfade with an high resolution image and ContentScale.FillWidth.

Issue:
The animation happens before the image is scaled, so at first you only see the top-left part of the image then it abruptly scales itself.

Initial flicker when using ProvideWindowInsets

I think the issue is that we only request insets once a composition has happened. The starting values are all 0 the initial layout of your composables will be as if there were no insets.

On the first composition we request insets, then need to wait for the next view layout pass (for dispatch), then the next composition to update the right values, then the new Compose layout.

AFAICT This is mostly an issue for apps which use Fragments and then ProvideWindowInsets in each, since all the above happens on each fragment view creation. We should investigate if there is a way for us to provide an API which allows fragments to 'prime' the values earlier.

Raised by @apkelly

DrawShadow causes weird boxing of some images

I have integrated CoilImage, so far its awesome! Thanks for your time into this extension

I have a problem when I try to add a back shadow to each image, it seems like for some images it renders ok the shadow with the elevation, but for some others it's likely to draw the shadow ok but the image inside is placed in a diamond fashion

Maybe is an error on my side, but is weird that some images are loaded ok and the others like this

Captura de pantalla 2020-09-17 a la(s) 10 41 59

Code

@Composable
private fun UserRow(user:User,onUserClick: (User) -> Unit) {
    Row(modifier = Modifier.clickable(onClick = { onUserClick(user) }).fillMaxWidth().padding(8.dp)) {
        val imageModifier = Modifier.preferredSize(46.dp).drawShadow(elevation = 4.dp, shape = CircleShape)
        CoilImage(data = user.profilePicutre,modifier = imageModifier,contentScale = ContentScale.Crop)
        Column (modifier = Modifier.padding(start = 8.dp).align(Alignment.CenterVertically)){
            Text(text = user.name, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.h6)
            ProvideEmphasis(EmphasisAmbient.current.medium) {
                Text(text = user.bio,style = MaterialTheme.typography.body2)
            }

        }
    }
}

Android Studio 4.2 canary 10 Preview Render Problem: java.lang.AssertionError: Unsupported Service: activity

Whenever you use @Composable CoilImage() or @Composable CoilImageWithCrossfade(), Compose @Preview shows a rendering problem saying:

java.lang.AssertionError: Unsupported Service: activity
	at com.android.layoutlib.bridge.android.BridgeContext.getSystemService(BridgeContext.java:669)
	at android.content.Context.getSystemService(Context.java:3705)
	at androidx.core.content.ContextCompat.getSystemService(ContextCompat.java:716)
	at coil.util.Utils.getDefaultAvailableMemoryPercentage(Utils.kt:86)
	at coil.ImageLoader$Builder.<init>(ImageLoader.kt:109)
	at coil.ImageLoader$Companion.create(ImageLoader.kt:449)
	at coil.Coil.newImageLoader(Coil.kt:77)
	at coil.Coil.imageLoader(Coil.kt:24)
	at dev.chrisbanes.accompanist.coil.CoilImage__CoilKt.CoilImage(Coil.kt:84)
	at dev.chrisbanes.accompanist.coil.CoilImage.CoilImage(CoilImage>)
	at com.example.jetsnack.ui.components.SnacksKt$SnackImage$1.invoke(Snacks.kt:262)
	at com.example.jetsnack.ui.components.SnacksKt$SnackImage$1.invoke(Snacks.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at com.example.jetsnack.ui.components.SurfaceKt$JetsnackSurface$1.invoke(Surface.kt:62)
	at com.example.jetsnack.ui.components.SurfaceKt$JetsnackSurface$1.invoke(Surface.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.foundation.BoxKt.Box-mP80RHo(Box.kt:109)
	at com.example.jetsnack.ui.components.SurfaceKt.JetsnackSurface-biUpMIw(Surface.kt:52)
	at com.example.jetsnack.ui.components.SnacksKt.SnackImage-SPfEvbc(Snacks.kt:256)
	at com.example.jetsnack.ui.components.SnacksKt$SnackItem$1.invoke(Snacks.kt:169)
	at com.example.jetsnack.ui.components.SnacksKt$SnackItem$1.invoke(Snacks.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at com.example.jetsnack.ui.components.SurfaceKt$JetsnackSurface$1.invoke(Surface.kt:62)
	at com.example.jetsnack.ui.components.SurfaceKt$JetsnackSurface$1.invoke(Surface.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.foundation.BoxKt.Box-mP80RHo(Box.kt:109)
	at com.example.jetsnack.ui.components.SurfaceKt.JetsnackSurface-biUpMIw(Surface.kt:52)
	at com.example.jetsnack.ui.components.SnacksKt.SnackItem(Snacks.kt:159)
	at com.example.jetsnack.ui.components.SnacksKt$Snacks$1.invoke(Snacks.kt:147)
	at com.example.jetsnack.ui.components.SnacksKt$Snacks$1.invoke(Snacks.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:151)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.foundation.ScrollKt.ScrollableRow(Scroll.kt:511)
	at com.example.jetsnack.ui.components.SnacksKt.Snacks(Snacks.kt:144)
	at com.example.jetsnack.ui.components.SnacksKt.SnackCollection(Snacks.kt:105)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$Body$1$1$1.invoke(SnackDetail.kt:194)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$Body$1$1$1.invoke(SnackDetail.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at com.example.jetsnack.ui.components.SurfaceKt$JetsnackSurface$1.invoke(Surface.kt:62)
	at com.example.jetsnack.ui.components.SurfaceKt$JetsnackSurface$1.invoke(Surface.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.foundation.BoxKt.Box-mP80RHo(Box.kt:109)
	at com.example.jetsnack.ui.components.SurfaceKt.JetsnackSurface-biUpMIw(Surface.kt:52)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$Body$1$1.invoke(SnackDetail.kt:154)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$Body$1$1.invoke(SnackDetail.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:151)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.foundation.ScrollKt.ScrollableColumn(Scroll.kt:462)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt.Body(SnackDetail.kt:152)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt.access$Body(SnackDetail.kt)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$SnackDetail$1.invoke(SnackDetail.kt:102)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$SnackDetail$1.invoke(SnackDetail.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:151)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.foundation.layout.StackKt$Stack$stackChildren$1.invoke(Stack.kt:54)
	at androidx.compose.foundation.layout.StackKt$Stack$stackChildren$1.invoke(Stack.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.ui.LayoutKt.Layout(Layout.kt:675)
	at androidx.compose.foundation.layout.StackKt.Stack(Stack.kt:56)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt.SnackDetail(SnackDetail.kt:99)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$SnackDetailDarkPreview$1.invoke(SnackDetail.kt:369)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt$SnackDetailDarkPreview$1.invoke(SnackDetail.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.compose.foundation.TextKt.ProvideTextStyle(Text.kt:241)
	at androidx.compose.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:71)
	at androidx.compose.material.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.compose.material.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:65)
	at com.example.jetsnack.ui.theme.ThemeKt$JetsnackTheme$2.invoke(Theme.kt:95)
	at com.example.jetsnack.ui.theme.ThemeKt$JetsnackTheme$2.invoke(Theme.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at com.example.jetsnack.ui.theme.ThemeKt.ProvideJetsnackColors(Theme.kt:228)
	at com.example.jetsnack.ui.theme.ThemeKt.JetsnackTheme(Theme.kt:94)
	at com.example.jetsnack.ui.snackdetail.SnackDetailKt.SnackDetailDarkPreview(SnackDetail.kt:368)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at androidx.ui.tooling.preview.PreviewUtilsKt.invokeComposableMethod(PreviewUtils.kt:141)
	at androidx.ui.tooling.preview.PreviewUtilsKt.invokeComposableViaReflection(PreviewUtils.kt:180)
	at androidx.ui.tooling.preview.ComposeViewAdapter$init$1$1$composable$1.invoke(ComposeViewAdapter.kt:371)
	at androidx.ui.tooling.preview.ComposeViewAdapter$init$1$1$composable$1.invoke(ComposeViewAdapter.kt)
	at androidx.ui.tooling.preview.ComposeViewAdapter$init$1$1.invoke(ComposeViewAdapter.kt:403)
	at androidx.ui.tooling.preview.ComposeViewAdapter$init$1$1.invoke(ComposeViewAdapter.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.ui.tooling.InspectableKt.Inspectable(Inspectable.kt:62)
	at androidx.ui.tooling.preview.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.kt:328)
	at androidx.ui.tooling.preview.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.ui.tooling.preview.ComposeViewAdapter.WrapPreview(ComposeViewAdapter.kt:327)
	at androidx.ui.tooling.preview.ComposeViewAdapter.access$WrapPreview(ComposeViewAdapter.kt)
	at androidx.ui.tooling.preview.ComposeViewAdapter$init$1.invoke(ComposeViewAdapter.kt:364)
	at androidx.ui.tooling.preview.ComposeViewAdapter$init$1.invoke(ComposeViewAdapter.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.ui.selection.SelectionContainerKt$SelectionContainer$3$1.invoke(SelectionContainer.kt:88)
	at androidx.compose.ui.selection.SelectionContainerKt$SelectionContainer$3$1.invoke(SelectionContainer.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.ui.LayoutKt.Layout(Layout.kt:675)
	at androidx.compose.ui.selection.SelectionLayoutKt.SelectionLayout(SelectionLayout.kt:80)
	at androidx.compose.ui.selection.SelectionContainerKt$SelectionContainer$3.invoke(SelectionContainer.kt:85)
	at androidx.compose.ui.selection.SelectionContainerKt$SelectionContainer$3.invoke(SelectionContainer.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.compose.ui.selection.SelectionContainerKt.SelectionContainer(SelectionContainer.kt:82)
	at androidx.compose.ui.selection.SelectionContainerKt.SelectionContainer(SelectionContainer.kt:39)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$1$1.invoke(Wrapper.kt:274)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$1$1.invoke(Wrapper.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.compose.ui.platform.AmbientsKt.ProvideCommonAmbients(Ambients.kt:109)
	at androidx.compose.ui.platform.AndroidAmbientsKt$ProvideAndroidAmbients$3.invoke(AndroidAmbients.kt:101)
	at androidx.compose.ui.platform.AndroidAmbientsKt$ProvideAndroidAmbients$3.invoke(AndroidAmbients.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.compose.ui.platform.AndroidAmbientsKt.ProvideAndroidAmbients(AndroidAmbients.kt:93)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$1.invoke(Wrapper.kt:273)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$1.invoke(Wrapper.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.AmbientKt.Providers(Ambient.kt:175)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.kt:272)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.kt)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt:142)
	at androidx.compose.runtime.internal.ComposableLambda.invoke(ComposableLambda.kt)
	at androidx.compose.runtime.ComposerKt.invokeComposable(Composer.kt:2686)
	at androidx.compose.runtime.Composer.composeInitial(Composer.kt:1853)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:241)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:110)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.kt:264)
	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.kt)
	at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.kt:557)
	at android.view.View.dispatchAttachedToWindow(View.java:20479)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3489)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3496)
	at android.view.AttachInfo_Accessor.setAttachInfo(AttachInfo_Accessor.java:44)
	at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:354)
	at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:435)
	at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141)
	at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:704)
	at com.android.tools.idea.rendering.RenderTask.lambda$inflate$6(RenderTask.java:859)
	at com.android.tools.idea.rendering.RenderExecutor$runAsyncActionWithTimeout$2.run(RenderExecutor.kt:174)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

This stacktrace from Jetsnack sample app, but also I wrote some compose code for Sunflower and encountered the same issue

Support for WindowInsetsAnimation

With the introduction of Insets to accompanist, are there any plans to add support for WindowInsetsAnimation? This allows fine grain control and coordination of the keyboard animation (as described in this article):

I found some code that shows how to add the callback within MainActivity, but it's not a jetpack compose app and so the content property isn't available:
https://github.com/siyehua/WindowInsetsAnimation/blob/a31ea8f5d73d29fcfcaa8f7386b66ed7297f8aea/app/src/main/java/com/example/myapplication/MainActivity.kt

CoilImage: Size modifier not working properly when drawable data is passed.

I am trying to display a drawable via CoilImage but when setting its size whether via size or preferredSize the image is not centered properly and have seemed to be crop and not centered. Although I seemed to have found a slight workaround where you set CircleCropTransform and it will work just fine, or I can also remove the size modifier and let it set its own size. But I do not want the image to be cropped and also I want to be able to set the size.

Here is my code snippet and the image of what happens

CoilImage(
    data = remember {
        ContextCompat.getDrawable(
            context,
            R.mipmap.ic_launcher
        )!!
    }
    modifier = Modifier.preferredSize(100.dp)
)

image

Compose Version: 1.0.0-alpha08

When many images are loaded from the remote URL and displayed to LazyColumnForIndexed, there will be a stutter problem when sliding.

When many images are loaded from the remote URL and displayed to LazyColumnForIndexed, there will be a stutter problem when sliding. A remote image loading component that I simply implemented by myself also has similar problems, but my implementation is implemented through onCommit().

running result:

my code:

@Composable
fun App(){
    Surface(color = MaterialTheme.colors.background) {
        LazyGridFor(items = getImages(), rowSize = 4) {
            CoilImage(data = it)
        }
    }
}

@Composable
fun <T> LazyGridFor(
    items: List<T>,
    rowSize: Int = 1,
    itemContent: @Composable BoxScope.(T) -> Unit
) {
    val rows = items.chunked(rowSize)
    LazyColumnForIndexed(rows) { index, row ->
        Row(Modifier.fillParentMaxWidth(1f)) {
            for ((index, item) in row.withIndex()) {
                Box(Modifier.fillMaxWidth(1f / (rowSize - index))) {
                    itemContent(item)
                }
            }
        }
    }
}

Thank you for your contribution!👍

Pluggable Fade Animation

Hi,

Thanks for the great library!

In a future release would it be possible to allow for an easy override of the painter.fadeIn animation in MaterialImageLoader to allow for alternate fade animations whilst keeping access to the current built-in logic around skipping fades if the image is loaded from memory?

Thanks

ime paddings too big

I try to use the animated ime padding values for my animation, but the values seem too big for me. I might use it wrong.

class MainActivity : AppCompatActivity() {

    @ExperimentalAnimatedInsets
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        WindowCompat.setDecorFitsSystemWindows(window, false)

        setContent {
            ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
                Box(Modifier.fillMaxSize()) {
                    TextField(
                        value = "",
                        onValueChange = {},
                        modifier = Modifier
                            .align(Alignment.BottomCenter)
                            .navigationBarsPadding()
                            .padding(bottom = AmbientWindowInsets.current.ime.bottom.dp)
                    )
                }
            }
        }
    }
}

Bildschirmfoto 2020-12-06 um 12 02 05

ime

[Idea] Provide inset aware layouts

We could make it easier to support insets, through a custom Scaffold implementation, as well making InsetAwareTopAppBar a real thing ™️

Candidates:

  • Scaffold
  • TopAppBar
  • BottomNavigation
  • ModalDrawerLayout
  • BottomAppBar (less priority)

`PicassoImage` doesn't scale correctly when `Modifier.aspectRatio()` is used

I have a sample app that I was working on for a blog post.

In the picasso-bug branch, I use a PicassoImage like this (link to code):

    PicassoImage(
        data = imageUrl,
        modifier = modifier.aspectRatio(16f / 9f),
        fadeIn = true,
        contentScale = ContentScale.Crop,
    )

screencap-1602620231

I do not see this same behavior with CoilImage however. On the master branch, I am using this code:

    CoilImage(
        data = imageUrl,
        modifier = modifier.aspectRatio(16f / 9f),
        fadeIn = true,
        contentScale = ContentScale.Crop,
    )

screencap-1602620122

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.