This question already has an answer here:
Why Compose Card not clickable?
(1 answer)
Closed 1 year ago.
I have a composable with an expandable Card view.
#Composable
fun ItemCard() {
var isExpanded by remember { mutableStateOf(false) }
Card(modifier = Modifier.clickable {
isExpanded = !isExpanded
Log.d(TAG, "Expanded set to $isExpanded")
}) {
// regular card segment goes here
AnimatedVisibility (isExpanded) {
// expanded card segment goes here
}
}
}
So, I updated compose to 1.0.0-beta08 and Modifier.clickable stoped working.
Here are the dependencies:
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.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.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.0-alpha08'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
implementation "androidx.navigation:navigation-compose:2.4.0-alpha01"
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha07"
implementation 'androidx.room:room-common:2.3.0'
implementation 'androidx.room:room-ktx:2.3.0'
implementation "androidx.room:room-runtime:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
All I changed was changing compose from 1.0.0-beta07 to 1.0.0-beta08 and (as required by the compose update) changing classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32" to classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
Cause:
This is a Behaviour Breaking API change from 1.0.0-beta07 to 1.0.0-beta08 as mentioned in release notes for Jetpack Compose.
Jetpack compose Version 1.0.0-beta08 Behavior Breaking API Change
BEHAVIOUR-BREAKING:
Card now consumes clicks, making clicks added via Card(Modifier.clickable) to be a no-op. Please, use new experimental overload of a Card that accepts onClick. (Ia8744, b/183775620)
Solution:
The solution provided is an overload of Card which allows handling clicks alongside related properties like indication, interactionSource, enabled/disabled.
Added a new Card overload that handles clicks as well as other clickable functionality: indication, interactionSource, enabled/disabled. It wasn't possible to use a regular non-clickable Card with the Modifier.clickable because the Card will not clip the ripple indication in those cases.
Card overload:
Here is the new Card overload which exposes onClick as well as interactionSource and indication.
#Composable
fun Card(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = MaterialTheme.shapes.medium,
backgroundColor: Color = MaterialTheme.colors.surface,
contentColor: Color = contentColorFor(backgroundColor),
border: BorderStroke? = null,
elevation: Dp = 1.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
indication: Indication? = LocalIndication.current,
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
content: #Composable () -> Unit
)
Related
I am using compose 1.1.1 in my jetpack compose. I cannot update to latest version. I am want something like this solution. I am getting error on my weight modifier. Can someone guide me how can I get my weight modifier in Row?
implementation "androidx.compose.runtime:runtime:$compose_version"
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.foundation:foundation-layout:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
androidTestImplementation "androidx.compose.ui:ui-test:$compose_version"
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation "androidx.activity:activity-compose:$compose_version"
Row.kt
Column {
Row(
modifier = Modifier.weight(1f, false)
) {
//...
}
}
Error
Expression 'weight' cannot be invoked as a function. The function 'invoke()' is not found
Many Thanks
UPDATE
I am adding my whole code here please have a look...
#Composable
fun Input(optionData: OptionData) {
Column(
modifier = Modifier
.fillMaxSize()
) {
Item(optionData)
}
}
#Composable
fun Item(optionData: OptionData) {
/// more item of compose i.e. Text, Textfield
Submit()
}
#Composable
fun Submit() {
Row(
modifier = Modifier.weight(1f, false)
) {
//...
}
}
UPDATE 2
After trying #Thracian solution it solve the problem of weight but my view is not going to bottom.
#Composable
fun Submit() {
Column {
OnSubmit {
PrimaryMaterialButton(text = stringResource(id = R.string.submit)) {
}
}
}
}
#Composable
fun ColumnScope.OnSubmit(content: #Composable () -> Unit) {
Row(
modifier = Modifier.weight(1f, false)
) {
content()
}
}
#Composable
fun Submit() {
Row(
modifier = Modifier.weight(1f, false)
) {
//...
}
}
For this code to be able to access Modifier.weight() from Column it should have receiver as ColumnScope. Some modifiers are created with scope so they are available only inside that scope such as Modifier.weight for Row or Column or Modifier.matchParentSize for Box.
#Composable
fun ColumnScope.Submit() {
Row(
modifier = Modifier.weight(1f, false)
) {
//...
}
}
// Allowed
Column {
Submit()
}
//Not Allowed
Row() {
Submit()
}
In Jetpack Compose, where is ScrollToTopButton coming from? It is mentioned in Google's documentation. Annoyingly, they neglect to mention the package. I have imports of foundation version 1.2.0-alpha08; also tried with 1.2.0-beta02 as well as ui and material (1.1.1). Not found. (yes did do an internet search on the term, came back empty handed).
implementation "androidx.compose.foundation:foundation:${version}"
implementation "androidx.compose.foundation:foundation-layout:${version}"
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
#Composable
fun MessageList(messages: List<Message>) {
val listState = rememberLazyListState()
// Remember a CoroutineScope to be able to launch
val coroutineScope = rememberCoroutineScope()
LazyColumn(state = listState) {
// ...
}
ScrollToTopButton(
onClick = {
coroutineScope.launch {
// Animate scroll to the first item
listState.animateScrollToItem(index = 0)
}
}
)
}
Google documentation
Edit: If this is NOT a function they offer, but rather a suggestion to create your own, shame on whoever wrote the documentation, it literally suggests being a function offered by Compose.
Edit 2: Turns out it is a custom function (see the answer). What moved the author of the documentation to write it like this? Why not just put Button? Sigh.
It's not clear from the documentation but you actually have to make your own. For example you can use this:
#Composable
fun ScrollToTopButton(onClick: () -> Unit) {
Box(
Modifier
.fillMaxSize()
.padding(bottom = 50.dp), Alignment.BottomCenter
) {
Button(
onClick = { onClick() }, modifier = Modifier
.shadow(10.dp, shape = CircleShape)
.clip(shape = CircleShape)
.size(65.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.White,
contentColor = Color.Green
)
) {
Icon(Icons.Filled.KeyboardArrowUp, "arrow up")
}
}
}
And then:
val showButton by remember{
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}
AnimatedVisibility(
visible = showButton,
enter = fadeIn(),
exit = fadeOut(),
) {
ScrollToTopButton(onClick = {
scope.launch {
listState.animateScrollToItem(0)
}
})
}
Unable to gain focus on any compose component. It use to work in the project but after some gradle changes, only in some screens i can request focus. So i started a new project to test out the behavior in a clean environment. With this setup, onFocusChange gets the values "inactive" before requestFocus (which is correct) then changes to "deactivated", and after requestFocus, nothing. This is a new project with almost no code
#Composable
fun Greeting(name: String) {
val focusRequester = remember { FocusRequester() }
Button(
onClick = {},
modifier = Modifier
.focusRequester(focusRequester = focusRequester)
.onFocusChanged {
it
}
.wrapContentSize()
,
) {
Text(text = "Hello $name!")
}
LaunchedEffect(Unit) {
this.coroutineContext.job.invokeOnCompletion {
focusRequester.requestFocus()
}
}
}
And in my build.gradle, where compose_version = 1.1.1
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
implementation 'androidx.activity:activity-compose:1.4.0'
}
You NEED to add the focusable modifier. It should come AFTER the onFocusChanged and focusRequestor Modifiers, and can also be replaced by focusTarget in some cases. See focusRequestor
I am trying to migrate an app from XML layouts to jetpack compose. As the app allows setting different user themes, I wanted to use the XML themes until all files are migrated. However, I just can't get it to work.
Basically I am doing as described in
https://material-components.github.io/material-components-android-compose-theme-adapter/#compose-material-3
I have a simple activity with a defined Composable:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import at.example.myapp.ui.composables.about.About
import com.google.android.material.composethemeadapter3.Mdc3Theme
class AboutActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(MainActivity.getUserTheme(this))
super.onCreate(savedInstanceState)
setContent {
// Use MdcTheme instead of MaterialTheme
// Colors, typography, and shape have been read from the
// View-based theme used in this Activity
Mdc3Theme {
About()
}
}
}
}
setTheme(...) correctly loads the theme, the color on the very top is corretly set, but nothing else. All other colors, styles and fonts are not set in the composable.
The About() composable itself has nothing special, just a few texts, images and a card.
I am importing the following versions:
//JETPACK COMPOSE
// Integration with activities
implementation 'androidx.activity:activity-compose:1.4.0'
// Compose Material Design
implementation 'androidx.compose.material:material:1.1.1'
// Animations
implementation 'androidx.compose.animation:animation:1.1.1'
// Tooling support (Previews, etc.)
implementation 'androidx.compose.ui:ui-tooling:1.1.1'
// Integration with ViewModels
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1'
// UI Tests
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.1.1'
// Theme compatibility with XML
implementation "com.google.android.material:compose-theme-adapter-3:1.0.6"
So the compose-theme-adapter-3 should actually do the job (if I understood the documentation correctly).
I played around with different combinations and parameters for Mdc3Theme { ... }, but without success, the colors won't just load.
In the resources I have the colors defined as expected by Material 3:
<resources>
<!-- Base application theme. -->
<style name="Theme.MyApp" parent="Theme.Material3.Light.NoActionBar">
<item name="colorPrimary">#color/md_theme_light_primary</item>
<item name="colorOnPrimary">#color/md_theme_light_onPrimary</item>
<item name="colorPrimaryContainer">#color/md_theme_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">#color/md_theme_light_onPrimaryContainer</item>
<item name="colorSecondary">#color/md_theme_light_secondary</item> ...
As I couldn't find other examples, I hope that it is correct to just basically load the Theme like this:
setContent {
// Use MdcTheme instead of MaterialTheme
// Colors, typography, and shape have been read from the
// View-based theme used in this Activity
Mdc3Theme {
About()
}
}
Playing around with compose-theme-adapter (for Material 2) also didn't help.
I'm really stuck here. Is there anyone who could help or give an example about how to get the Mdc3 Theme applied properly from XML?
EDIT:
For completion, here's also the About() Composable:
#Composable
fun About() {
val defaultPadding = 8.dp
val widePadding = 16.dp
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
ImageVector.vectorResource(id = R.drawable.ic_babyfootsteps),
null,
modifier = Modifier
.padding(widePadding)
.size(100.dp, 100.dp)
.background(Color(0xFFFF0077))
)
Text(
stringResource(id = R.string.app_name),
fontSize = 24.sp,
modifier = Modifier.padding(defaultPadding),
)
Text(stringResource(id = R.string.about_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE))
Text(stringResource(id = R.string.about_app_codename, BuildConfig.versionCodename))
Spacer(modifier = Modifier.padding(defaultPadding))
...
While I was trying to use jetpack's compose library, I was stuck at following the step mentioned in jetpack documentation (source: https://developer.android.com/jetpack/compose/setup#compose-compiler). I was unable to use kotlinPlugin as I got the following exception.
Caused by: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method kotlinPlugin() for arguments [androidx.compose:compose-compiler:0.1.0-dev02] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
Also, I could not able to use darkThemeColors and lightThemeColors. Following are the Gradle dependencies I added.
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
kotlinPlugin "androidx.compose:compose-compiler:0.1.0-dev02"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.ui:ui-framework:0.1.0-dev02'
implementation 'androidx.ui:ui-layout:0.1.0-dev02'
implementation 'androidx.ui:ui-material:0.1.0-dev02'
implementation 'androidx.ui:ui-tooling:0.1.0-dev02'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.50'
}
Am I missing any dependency? I checked MaterialTheme and MaterialColors classes, but didn't find darkThemeColors and lightThemeColors.
In jetpackCompose sample app jetnews the darkThemeColors and lightThemeColors define in Themes.kt file exmaple below so you need define Colors.
val lightThemeColors = MaterialColors(
primary = Color(0xFFDD0D3C),
primaryVariant = Color(0xFFC20029),
onPrimary = Color.White,
secondary = Color.White,
onSecondary = Color.Black,
background = Color.White,
onBackground = Color.Black,
surface = Color.White,
onSurface = Color.Black,
error = Color(0xFFD00036),
onError = Color.White
)
/**
* Note: Dark Theme support is not yet available, it will come in 2020. This is just an example of
* using dark colors.
*/
val darkThemeColors = MaterialColors(
primary = Color(0xFFEA6D7E),
primaryVariant = Color(0xFFDD0D3E),
onPrimary = Color.Black,
secondary = Color(0xFF121212),
onSecondary = Color.White,
surface = Color(0xFF121212),
background = Color(0xFF121212),
onBackground = Color.White,
onSurface = Color.White
)
In below screenshot of jetnews project
For jetnews sample check this link https://developer.android.com/jetpack/compose/setup#sample
You can define darkThemeColors and lightThemeColors as you prefer.
With 1.0.0-beta02 just use the lightColors and darkColors functions.
Something like:
val purple500 = Color(0xFF6200EE)
private val LightColorPalette = lightColors(
primary = purple500,
primaryVariant = purple700,
secondary = Color(0xFF03DAC6),
onSecondary = Color.White
)
For example you can define:
#Composable
fun MaterialThemeSample(darkTheme: Boolean = isSystemInDarkTheme(), content: #Composable() () -> Unit) {
val lightColorsPalette = lightColors(
primary = Color(0xFF1EB980),
secondary = Color(0xFF03DAC6)
)
val darkColorsPalette = darkColors(
primary = Color(0xFF66ffc7),
secondary = Color.Red
)
val colors = if (darkTheme) darkColorsPalette else lightColorsPalette
MaterialTheme(
colors = colors,
typography = typography,
shapes = shapes,
content = content
)
}
and use it:
setContent {
MaterialThemeSample() {
.....
}
}