zt
09/27/2022, 11:21 PMelye
09/28/2022, 12:29 AMViewRootForInspector
. It is used by Dialog
, Popup
etc... I'm trying to understand how should it be used along with AbstractCompose
. Thanks 🙏svenjacobs
09/28/2022, 6:52 AMabu naser
09/28/2022, 7:00 AMHengjiang Liu
09/28/2022, 7:16 AMlazyColum
inside a LazyColum
and I need to do something use the NestedScrollConnection. I created two NestedScrollConnection
object, one for child and another one for parent. But I don’t know why the child’s available in onPostScroll()
can’t transit to parent while onPreScroll works fine. I wonder how to connect two NestedScrollConnection as child and parent, is it automatic?czuckie
09/28/2022, 7:32 AModay
09/28/2022, 7:59 AMTopAppBar
, the Composable itself has a parameter backgroundColor
, ok, but I was expecting to be able to change its background through Modifier as well…not only does that not work but it’s like you didn’t even pass anything to the modifier if you try that
setting backgroundColor on the TopAppBar does work thoughChristoph Wiesner
09/28/2022, 8:02 AMval iconContent: @Composable () -> Unit = {
Icon(...)
}
if (someCondition) {
// wrap the icon in a box to display some overlapping composable
Box(...) {
iconContent()
OverlayingComposable()
}
} else {
// 99% of the time the overlay is hidden - so only display the icon without the Box wrapper
iconContent()
}
is this unnecessary optimization? bc. readability gets worse - or is there another approach?Ruben Quadros
09/28/2022, 12:31 PMText
component?Jhonatan Sabadi
09/28/2022, 4:50 PMAndroidView(
factory = { context ->
TimePicker(context)
}
)
Chris Fillmore
09/28/2022, 6:08 PMposition: absolute
is in Compose.Mia Clapham
09/28/2022, 6:34 PM@Test
fun priceAlerts_LetsGoButton() {
setUpPriceAlertsComposable()
val button =
composeRule.onNodeWithText(context.getString(
R.string.improved_onboarding_V1_lets_go_button))
.assertExists()
button.assertIsDisplayed()
button.performClick().assertExists()
verify(mockViewModel).letsGoClick(any())
}
zt
09/28/2022, 10:59 PMFATAL EXCEPTION: main
Process: com.hyperion, PID: 13405
java.lang.ArrayIndexOutOfBoundsException: length=7430; index=7431
at androidx.compose.runtime.SlotTableKt.hasMark(SlotTable.kt:3169)
at androidx.compose.runtime.SlotTableKt.access$hasMark(SlotTable.kt:1)
at androidx.compose.runtime.SlotReader.hasMark(SlotTable.kt:827)
at androidx.compose.runtime.ComposerImpl.reportFreeMovableContent$reportGroup(Composer.kt:3500)
at androidx.compose.runtime.ComposerImpl.reportFreeMovableContent(Composer.kt:3593)
+ 300 more linesMarkus Fung
09/29/2022, 2:01 AMwillyrs
09/29/2022, 7:19 AMGuilherme Delgado
09/29/2022, 10:02 AMMarco Pierucci
09/29/2022, 10:30 AMfocusable:false
?Jasmin Fajkic
09/29/2022, 11:16 AMokaymak
09/29/2022, 11:55 AMTextField
? I basically want the TextField
to be just for input and without selection, magnifier, copy or paste.qlitzler
09/29/2022, 12:09 PMlouiscad
09/29/2022, 3:00 PMChuck Stein
09/29/2022, 3:51 PMNavHost
inside a ComposeView
in that Fragment?Chris Fillmore
09/29/2022, 4:15 PMAnimatedContent
that uses an enum for state. I’d like to switch to a sealed interface, to pass arguments, but I would lose the use of Enum.ordinal
. Any recommendations?Zach Klippenstein (he/him) [MOD]
09/29/2022, 4:22 PMzsperske
09/29/2022, 4:33 PMR.attr
references in a Compose Preview? We use attribute references & themes for colors/drawables/text styles, however when running a preview they don’t resolve properly. This Composable fails to render a Preview.
@Preview
@Composable
fun MyComposable() {
val attrPainter = attrPainter(R.attr.myAttr) //custom painter to get a drawable from an attr reference
Image(attrPainter, contentDescription = "some description")
}
MikeH
09/30/2022, 8:50 AMAnton Krutko
09/30/2022, 9:33 AMreactormonk
09/30/2022, 11:59 AMnuhkoca
09/30/2022, 1:48 PMLinearBrush
not RadialBrush
but it is not I expect. More in thread.Nikolas Guillen Leon
09/30/2022, 3:35 PMNikolas Guillen Leon
09/30/2022, 3:35 PMRichard Z
09/30/2022, 6:43 PMNikolas Guillen Leon
09/30/2022, 7:20 PMfun CartScreen(
productWrappers: List<ProdottoWrapper>,
totalCost: Float,
onUIEvent: (UIEvent) -> Unit,
loading: Boolean,
alertDialog: AlertDialog?
) {
val focusManager = LocalFocusManager.current
val listSize = productWrappers.size.toString()
Box(modifier = Modifier.fillMaxSize()) {
Scaffold(
bottomBar = {
SendOrderBar(
totalCost = totalCost,
onSendClick = { onUIEvent(Submit) }
)
}
) { paddingValues ->
Box(
modifier = Modifier
.fillMaxSize()
.clickable(
onClick = { if (!loading) focusManager.clearFocus() },
indication = null,
interactionSource = remember {
MutableInteractionSource()
}
)
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(horizontal = 16.dp)
) {
Text(
text = stringResource(R.string.carrello),
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(16.dp))
if (productWrappers.isNotEmpty()) {
Text(
text = listSize + stringResource(id = R.string.articoli_nel_carrello),
style = MaterialTheme.typography.subtitle1,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.height(16.dp))
ProductsListHeader()
Spacer(modifier = Modifier.height(8.dp))
Divider()
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(
items = productWrappers,
key = { productWrapper -> productWrapper.prodotto.id },
contentType = { productWrapper -> productWrapper }
) { productWrapper ->
RevealSwipe(
directions = setOf(RevealDirection.EndToStart),
hiddenContentEnd = {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = null,
tint = Color.White,
modifier = Modifier.padding(horizontal = 25.dp)
)
},
onBackgroundEndClick = { onUIEvent(Delete(productWrapper)) },
backgroundCardEndColor = Color.Red,
contentColor = Color.Black
) {
Box(
modifier = Modifier
.drawBehind {
drawRect(Color.White)
}
.padding(vertical = 10.dp)
) {
ProductRow(
productWrapper = productWrapper,
onUmChanged = { um -> onUIEvent(UmChanged(productWrapper, um)) },
onAdd = { onUIEvent(Add(productWrapper)) },
onRemove = { onUIEvent(Remove(productWrapper)) },
onEditQuantity = { quantity -> onUIEvent(EditQuantity(productWrapper, quantity)) },
onFocusRemoved = { onUIEvent(QuantityFocusOut(productWrapper)) }
)
}
}
Divider()
}
}
} else {
if (!loading) {
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = stringResource(R.string.carrello_nessun_articolo),
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
modifier = Modifier.align(Alignment.Center)
)
}
}
}
}
}
}
if (alertDialog != null) {
AlertDialog(
onDismissRequest = { alertDialog.onDismiss?.invoke() },
title = {
Text(
text = alertDialog.title,
fontWeight = FontWeight.Bold
)
},
text = { Text(text = alertDialog.msg) },
buttons = {
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
) {
if (alertDialog.onCancel != null) {
TextButton(onClick = alertDialog.onCancel::invoke) {
Text(
text = stringResource(id = R.string.annulla_label),
color = Color.Gray
)
}
}
if (alertDialog.onConfirm != null) {
TextButton(onClick = alertDialog.onConfirm::invoke) {
Text(
text = stringResource(id = R.string.ok_label),
color = Color.Gray
)
}
}
}
}
)
}
LoadingOverlay(isVisible = loading)
}
}
fun ProductRow(
productWrapper: ProdottoWrapper,
onUmChanged: (Um) -> Unit,
onAdd: () -> Unit,
onRemove: () -> Unit,
onEditQuantity: (String) -> Unit,
onFocusRemoved: () -> Unit
) {
val product = productWrapper.prodotto
val um = productWrapper.um
val price = productWrapper.prezzo
val quantity by remember(productWrapper.quantita) {
derivedStateOf {
productWrapper.quantita
}
}
var dropdownVisibility by remember { mutableStateOf(false) }
var dropdownWidth by remember { mutableStateOf(Size.Zero) }
Row(
modifier = Modifier
.fillMaxWidth()
.drawBehind {
drawRect(Color.White)
},
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.fillMaxWidth()
.weight(3f)
) {
Text(
text = "Cod. ${product.codice}",
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Visible
)
Text(
text = product.descrizione,
maxLines = 4,
overflow = TextOverflow.Ellipsis
)
Text(
text = "Prezzo unitario ${BuildConfig.VALUTA} ${
Formatter.formatPrezzo(
LocalContext.current, productWrapper.prezzo_unitario
)
}/${product.um_default.descrizione}",
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = colorResource(id = R.color.os_dark_grey),
maxLines = 1,
overflow = TextOverflow.Visible
)
}
Column(
modifier = Modifier
.fillMaxSize()
.weight(1f)
.onGloballyPositioned { layoutCoordinates ->
dropdownWidth = layoutCoordinates.size.toSize()
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
if (product.um.size > 1) {
Card(
backgroundColor = Color.Transparent,
border = BorderStroke(1.dp, colorResource(id = R.color.medium_dark)),
elevation = 0.dp,
modifier = Modifier
.fillMaxWidth()
.height(40.dp)
.clickable { dropdownVisibility = true },
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(all = 5.dp)
) {
Text(text = um.descrizione)
Icon(
imageVector = Icons.Default.KeyboardArrowDown,
contentDescription = ""
)
}
}
DropdownMenu(
expanded = dropdownVisibility,
onDismissRequest = { dropdownVisibility = false },
modifier = Modifier.widthIn(min = with(LocalDensity.current) { dropdownWidth.width.toDp() })
) {
product.um.forEach {
Row(modifier = Modifier
.clickable {
onUmChanged(it)
dropdownVisibility = false
}
.fillMaxWidth()
.padding(horizontal = 10.dp, vertical = 5.dp)) {
Text(text = it.descrizione, overflow = TextOverflow.Ellipsis)
}
}
}
} else {
Text(text = um.descrizione, fontWeight = FontWeight.Bold)
}
}
Column(
modifier = Modifier
.fillMaxSize()
.weight(2f)
.padding(horizontal = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
QuantitySelector(
quantity = quantity,
onAdd = onAdd,
onRemove = onRemove,
onEditQuantity = {
onEditQuantity(it)
},
onFocusRemoved = onFocusRemoved
)
}
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "${BuildConfig.VALUTA} ${
Formatter.formatPrezzo(
LocalContext.current,
price
)
}",
fontWeight = FontWeight.Bold,
textAlign = TextAlign.End
)
}
}
}
fun QuantitySelector(
quantity: String,
onAdd: () -> Unit,
onRemove: () -> Unit,
onEditQuantity: (String) -> Unit,
onFocusRemoved: () -> Unit
) {
val interactionSource = remember { MutableInteractionSource() }
val focused = remember { mutableStateOf(false) }
val focusManager = LocalFocusManager.current
Card(
backgroundColor = Color.Transparent,
border = BorderStroke(1.dp, colorResource(id = R.color.medium_dark)),
elevation = 0.dp,
modifier = Modifier
.wrapContentWidth()
.height(40.dp)
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = onRemove, modifier = Modifier.weight(1f)) {
Icon(
painter = painterResource(id = R.drawable.ic_baseline_remove_24),
contentDescription = null,
tint = colorResource(id = R.color.os_dark_grey),
modifier = Modifier.fillMaxSize(0.7f)
)
}
BasicTextField(
value = quantity,
onValueChange = {
onEditQuantity(it)
},
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
singleLine = true,
interactionSource = interactionSource,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(onDone = {
onFocusRemoved()
focusManager.clearFocus()
}),
modifier = Modifier
.weight(2f)
.fillMaxWidth()
.onFocusChanged {
if (!it.isFocused && focused.value) {
onFocusRemoved()
}
focused.value = it.isFocused
}
) {
TextFieldDefaults.TextFieldDecorationBox(
value = quantity,
innerTextField = it,
enabled = true,
singleLine = true,
visualTransformation = VisualTransformation.None,
interactionSource = interactionSource,
contentPadding = TextFieldDefaults.textFieldWithoutLabelPadding(
top = 0.dp,
bottom = 0.dp,
start = 0.dp,
end = 0.dp
)
)
}
IconButton(onClick = onAdd, modifier = Modifier.weight(1f)) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = null,
tint = colorResource(id = R.color.os_dark_grey),
modifier = Modifier.fillMaxSize(0.7f)
)
}
}
}
}