so after jetpack compose beta was released, I updated my Android Studio Canary to the latest version, but I can't preview my app, even when I annotate my code with #Preview, there is no button called show preview or show code, they just disappeared.
Your UI code needs to be inside a compose fuction.
#Composable
fun Greeting(name: String) {
Text (text = "Hello $name!")
}
The composable function must not take any parameters. For this reason, you can't preview the Greeting() function directly. Instead, make a second function named PreviewGreeting(), which calls Greeting() with an appropriate parameter. Add the #Preview annotation before #Composable.
#Preview
#Composable
fun PreviewGreeting() {
Greeting("Android")
}
after 1 day I realized that I had to download Android Studio Canary from the website, and all thing worked just fine with the new compose beta.
Download the 'Android studio Arctic Fox' from this link
Related
I have defined the Kotlin reflection dependency in my Gradle file as follows:
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
Within the App, reflection works just fine. However, when I use reflection within a Composable preview:
#Composable
#Preview
fun MyComposablePreviewUsingReflection() {
val foo = SomeClass::class.sealedSubclasses.size
}
I get the kotlin.jvm.KotlinReflectionNotSupportedError. When I build the App and use reflection in a normal Composable (i.e., not a preview), reflection works just fine.
Is there a way to get reflection working in a Compose preview?
I'm just trying to get started with Android development and Kotlin using Jetpack Compose. Note that, I'm a Kotlin novice, so I'm trying to learn along the way. I come from JavaScript/TypeScript background, so I'm trying to learn by thinking in JavaScript terms and implement in Kotlin terms by searching online.
I'm trying to list all installed applications on the device. While the app was working as expected up till now, I needed to add a feature to sort the installed app names. I referred to: https://www.bezkoder.com/kotlin-sort-list-objects/#Create_Class_for_handling_sorting. As soon as I added a custom class to sort the List<ApplicationInfo>, my app stopped building.
I have included my repo here: https://github.com/Hrishikesh-K/TryKotlin
If I comment these lines and this line as well, the app builds fine. With the current setup, I get an error:
Functions which invoke #Composable functions must be marked with the #Composable annotation
which points to line 21, character 18, which is the start of the word compare.
I don't understand why Compose would care about a custom class, it's not a Composable function after all. What am I missing?
In the compare method you are using LocalContext.current
override fun compare(o1 : ApplicationInfo, o2 : ApplicationInfo): Int {
return o1.loadLabel(LocalContext.current.packageManager).toString().compareTo(o2.loadLabel(LocalContext.current.packageManager).toString())
}
You can't use a #Composable functions if the method is not marked with the #Composable.
Use something different like:
data class CompareApplicationNames(val context: Context) : Comparator<ApplicationInfo> {
override fun compare(o1 : ApplicationInfo, o2 : ApplicationInfo): Int {
return o1.loadLabel(context.packageManager).toString().compareTo(o2.loadLabel(context.packageManager).toString())
}
}
Then just use:
Log.d("sorted:", listOfApplications.sortedWith(CompareApplicationNames(LocalContext.current)).toString())
I noticed today that my preview doesn't work if I have a flow as a parameter to a Composable i.e. the below will always render as emptyMap()
#Composable
fun BakesList(
bakes: Flow<Map<Bake, List<Ingredient>>>,
) {
val bakesMap by bakes.collectAsState(initial = emptyMap())
LazyColumn {
//display columns
//...
}
}
If I change my Composable parameter to a Map<Bake, List<Ingredient>> then everything renders correctly. Is there a simple fix for this other than redesigning all my composables?
I've been exploring Jetpack Compose lately and discovered this very weird scenario where my #Preview is not showing and Android Studio is literally showing blank empty. No warnings or errors are shown.
This happens when I add #PreviewParameter to my composable function parameter.
The stupid solution was… It turns out that I had my PreviewParameterProvider declared in private and turning it to public or simply removing the visibility modifier fixed it.
class MyProvider : PreviewParameterProvider<MyClass> {
...
}
This wasn't even documented.
I hope Google will make it clear in the documentation or at least give an error in Android Studio so developers won't encounter this frustrating and time-wasting scenario.
I had another issue causing the same behaviour.
blank screen
#Preview
#Composable
fun MyComposablePreview(
#PreviewParameter(MyComposableStateProvider::class) state: MyComposableState
) = MyComposable(state)
works
#Preview
#Composable
fun MyComposablePreview(
#PreviewParameter(MyComposableStateProvider::class) state: MyComposableState
) {
MyComposable(state)
}
I can also add that your implementation of PreviewParameterProvider should not be inner class and should not be inside other class. So
class MyFragment : Fragment() {
class MyProvider : PreviewParameterProvider<MyComposableStateProvider> {
...
}
#Preview
#Composable
fun MyComposablePreview(
#PreviewParameter(MyProvider::class) state: MyComposableState
) {
MyComposable(state)
}
}
won't work either. extract providers to separate files.
I've begun implementing a feature on my application with Jetpack Compose.
The application uses Swig to generate code that allows me to interact with a C++ layer from Kotlin/Java. In order to use the C++ layer, I load the library like this in the app's main activity:
static {
System.loadLibrary("{swig library name}");
}
When I attempt to use Jetpack Compose previews, I get the following render problem:
java.lang.UnsatisfiedLinkError: 'void {package containing swig's generated code}.swigWrappersJNI.swig_module_init()'
The function does use a class generated by Swig, so I'm assuming that's why this is happening.
I tried getting around this by adding the following to the preview function:
System.loadLibrary("{swig library name}")
but that just results in the following render problem:
java.lang.UnsatisfiedLinkError: no {swig library name} in java.library.path:
Does anybody know how/if I can properly link the library so that I can use Compose's preview feature as I work on this app?
Edit:
For a little more info, I've tried the following methods for loading my library:
#Composable
#Preview
fun ___Preview() {
System.loadLibrary("{swig library name}");
// Actual preview code here
}
object LibraryLoader {
fun load() {
System.loadLibrary("{swig library name}")
}
}
#Composable
#Preview
fun ___Preview() {
LibraryLoader.load()
// Actual preview code here
}
(This one was a bit of a shot in the dark. I thought the key difference could've been loading it within a static block, but this had no effect.)
The previews can be successfully deployed to a device/emulator.
I think the issue here is that the library lives in lib/{abi}/{swig library name}.so, so it exists when running on a device/emulator (with a supported ABI) but not for Compose previews.
What I've done to work around it is create a copy of my model classes that don't use any of Swig's generated code so I can take advantage of previews when creating the layout, then replacing them with the actual model classes for testing functionality. Definitely not a solution I'm particularly happy with but it may be the only way to use Compose previews in this type of situation.