• z

    zoha131

    1 year ago
    Today I am been trying to implement custom checkable button. I want the button to take all the available places. Unfortunately it only works if I wrap CategoryButton inside a Box. Without Box the text Does not get placed in a wrong way. A little help would be appreciated. Here is my code:
    import androidx.compose.animation.animate
    import androidx.compose.foundation.Canvas
    import androidx.compose.foundation.Image
    import androidx.compose.foundation.Text
    import androidx.compose.foundation.clickable
    import androidx.compose.foundation.layout.*
    import androidx.compose.foundation.shape.RoundedCornerShape
    import androidx.compose.material.MaterialTheme
    import androidx.compose.material.Surface
    import androidx.compose.material.icons.Icons
    import androidx.compose.material.icons.filled.Close
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.remember
    import androidx.compose.ui.Layout
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.draw.clip
    import androidx.compose.ui.geometry.Offset
    import androidx.compose.ui.graphics.Color
    import androidx.compose.ui.graphics.ColorFilter
    import androidx.compose.ui.graphics.drawscope.translate
    import androidx.compose.ui.layout.ContentScale
    import androidx.compose.ui.unit.Constraints
    import androidx.compose.ui.unit.dp
    import androidx.ui.tooling.preview.Preview
    
    @Composable
    fun CategoryButton(modifier: Modifier = Modifier) {
        val (checked, setChecked) = remember { mutableStateOf(false) }
        Surface(
            modifier = modifier
                .clip(RoundedCornerShape(4.dp))
                .clickable {
                    setChecked(!checked)
                },
            shape = RoundedCornerShape(4.dp)
        ) {
            CategoryButtonLayout(isChecked = checked, modifier = modifier)
        }
    }
    
    @Composable
    private fun CategoryButtonLayout(isChecked: Boolean, modifier: Modifier) {
        Layout(
            children = { CategoryButtonContent(isChecked) },
            modifier = modifier,
            measureBlock = { miserables, constraints ->
                val width = constraints.maxWidth
                val height = 48.dp.toIntPx()
    
                val canvasConstraints = Constraints(
                    maxHeight = height,
                    minHeight = height,
                    maxWidth = width,
                    minWidth = width
                )
    
                val iconSize = 24.dp.toIntPx()
                val iconConstraints = Constraints(
                    minHeight = iconSize,
                    maxHeight = iconSize,
                    minWidth = iconSize,
                    maxWidth = iconSize
                )
    
                val canvasPlaceable = miserables[0].measure(canvasConstraints)
                val iconPlaceable = miserables[1].measure(iconConstraints)
                val textPlaceable = miserables[2].measure(constraints)
    
                layout(width, height) {
                    canvasPlaceable.place(0, 0)
                    iconPlaceable.place(8, height / 2 - iconPlaceable.height / 2)
                    textPlaceable.place(iconSize, height / 2 - textPlaceable.height / 2)
                }
            }
        )
    }
    
    @Composable
    private fun CategoryButtonContent(isChecked: Boolean) {
        val textColor = if (isChecked) Color.White else Color.Black
        val textColorAnimated = animate(textColor)
    
        val radius = if (isChecked) 550.dp else 4.dp
        val radiusAnimated = animate(radius)
    
        Canvas(
            modifier = Modifier.fillMaxSize(),
            onDraw = {
    
                val left = size.width / 2
                // To move the center of the circle
                translate(left, 0f) {
                    drawCircle(color = Color.Red, radius = radiusAnimated.toIntPx().toFloat())
                }
    
                drawLine(
                    color = Color.Red,
                    start = Offset(size.width, 0f),
                    end = Offset(size.width - 8.dp.toIntPx().toFloat(), 0f),
                    strokeWidth = size.width
                )
            }
        )
    
        Image(
            asset = Icons.Filled.Close,
            colorFilter = ColorFilter.tint(textColorAnimated),
            contentScale = ContentScale.Fit
        )
    
        Text(
            style = MaterialTheme.typography.button.copy(color = textColorAnimated),
            text = "COVID 19",
            maxLines = 1
        )
    }
    
    @Preview
    @Composable
    fun CategoryButtonPreview() {
        Box(
            Modifier.fillMaxWidth()
        ) {
            CategoryButton()
        }
    }
    
    @Preview
    @Composable
    fun CategoryButtonRowBoxPreview() {
        Row(
            Modifier.fillMaxWidth()
        ) {
            Box(
                Modifier.fillMaxWidth().weight(1f)
            ) {
                CategoryButton()
            }
    
            Box(
                Modifier.fillMaxWidth().weight(1f)
            ) {
                CategoryButton()
            }
        }
    }
    
    @Preview
    @Composable
    fun CategoryButtonRowPreview() {
        Row(
            Modifier.fillMaxWidth()
        ) {
    
            CategoryButton(
                modifier = Modifier.fillMaxWidth().weight(1f)
            )
    
            CategoryButton(
                modifier = Modifier.fillMaxWidth().weight(1f)
            )
        }
    }
    z
    Afzal Najam
    +1
    5 replies
    Copy to Clipboard
  • Afzal Najam

    Afzal Najam

    1 year ago
    Hi, I wrote a two-part blog post about how to use the new navigation-compose library (still pre-alpha). First part is normal use cases, second part is about using it with bottom navigation (and also multiple nav graphs in each tab). Part 1: https://afzaln.com/intro-to-jetpack-compose-navigation/ Part 2: https://afzaln.com/multiple-navigation-graphs-with-jetpack-compose-navigation/
    Afzal Najam
    Ash
    +2
    9 replies
    Copy to Clipboard
  • d

    Daniele B

    1 year ago
    How can I see where the padding for
    TopAppBar
    are defined? I tried to look for its implementation (by hitting CMD-B), but it’s not available from Android Studio
    d
    Javier
    2 replies
    Copy to Clipboard
  • z

    zoha131

    1 year ago
    I am not getting any elevation or shadow for this:
    Surface(
                    elevation = 16.dp
                ) {
                    Text(text = "Hello World", modifier = Modifier.padding(16.dp))
                }
    But if I add
    Modifier.drawLayer(shadowElevation = 16f
    then I get shadow. Now my qs is. shouldn’t elevation give us the shadow/elevation?
    z
    Andrey Kulikov
    2 replies
    Copy to Clipboard
  • caelum19

    caelum19

    1 year ago
    Hey, sorry if this has been asked before, but is there plans for some easier way to share Composables? Creating a project just for that Composable and submitting it to jitpack, and then sticking it on your github for anyone lucky enough to stumble upon it isn't ideal. Now that Composables are so reusable and detached, something like a Composable marketplace for easier sharing, discovery, using and updating would be really cool
    caelum19
    v
    +2
    20 replies
    Copy to Clipboard
  • d

    Daniele B

    1 year ago
    Is there a way to make a word bold or italics within a Text in Jetpack Compose, without having to create different Texts for applying the bold or italics fontStyle?
    d
    n
    +1
    4 replies
    Copy to Clipboard
  • m

    mattinger

    1 year ago
    I also don’t want the button to go grey so setting enabled = false isn’t my answer i don’t think.
    m
    Javier
    +3
    35 replies
    Copy to Clipboard
  • Tash

    Tash

    1 year ago
    With Compose, is there (or will there be) a departure from using the ViewModel arch component to preserve state during config changes? Having the ViewModel (arch component) is great, but I wonder what’s next. In the very basic form they’re essentially state holders that give us a simple solution for handling config changes, and because of that very feature, they have the propensity to grow into monoliths of presentation/domain transactions.
    Tash
    i
    +2
    7 replies
    Copy to Clipboard
  • fabio.carballo

    fabio.carballo

    1 year ago
    hello, is there any way to show the layout bounds using the developer options? if not, what would be the most practical way to achieve the same effect?
    fabio.carballo
    Halil Ozercan
    2 replies
    Copy to Clipboard
  • Vsevolod Ganin

    Vsevolod Ganin

    1 year ago
    Found a strange behavior in
    LazyColumnFor
    . When I use positional
    remember
    inside
    itemContent
    , it remembers everything for that particular index in the list. So when I remove an item in the source list, the (index + 1) item takes its place and inherits the memory of its predecessor. I think that’s because of the usage of
    key(index)
    in
    LazyColumnFor
    implementation. Is this intended?
    Vsevolod Ganin
    Zach Klippenstein (he/him) [MOD]
    4 replies
    Copy to Clipboard