https://kotlinlang.org logo
#compose
Title
# compose
o

Oliver

03/06/2024, 8:19 AM
Hello! kodee greetings I need some help either figuring out how to do this in Compose or I will have to make some sort of feature request if it is not possible yet. I have a design requirement that application top and bottom bars are partially transparent, the scrollable area should continue behind the bars. This means i cannot apply the regular padding to scrollable column and will have to resort to setting content padding. However this content padding is not taken into account when scrolling focused elements into view. I'd want the text fields to be scrolled into view properly, without bars covering up the focused field. The code for this dummy screen is in 🧵
Copy code
@Composable
@Preview
fun App() {
    MaterialTheme {
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background,
        ) {
            Screen()
        }
    }
}

@Composable
private fun Screen() {
    Scaffold(
        topBar = { TopBar() },
        bottomBar = { BottomBar() },
    ) { contentPadding ->
        LazyColumn(
            verticalArrangement = Arrangement.spacedBy(24.dp),
            contentPadding = contentPadding,
            modifier = Modifier.fillMaxWidth(),
        ) {
            items((0 ..< 4).toList()) {
                OutlinedTextField(
                    value = "placeholder $it",
                    onValueChange = {},
                    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
                    minLines = 6,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 24.dp),
                )
            }
        }
    }
}

@Composable
private fun BottomBar() {
    BottomAppBar(
        containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.8F),
    ) {
        Text(
            text = "Bottom bar",
            textAlign = TextAlign.Center,
            modifier = Modifier.fillMaxWidth(),
        )
    }
}

@Composable
@OptIn(ExperimentalMaterial3Api::class)
private fun TopBar() {
    CenterAlignedTopAppBar(
        title = { Text("Top bar") },
        colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
            containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.8F),
        ),
    )
}
And to be precise, the imports are:
Copy code
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
One of the options I see is to use
BringIntoViewRequester
and provide the
Rect
to it. However getting the exact rect values isn't very straightforward in my non-example case. I am not even entirely sure whether the rect is used the way I think it would be used.
s

Stylianos Gakis

03/06/2024, 12:24 PM
Maybe file a bug for this? I can imagine how the content padding isn't considered for the focus scenario, but also I see how it's very inconvenient that it doesn't handle that. Maybe it's a known issue, or there's a known thing you can do. If you do file it link it back here I am curious as well
o

Oliver

03/06/2024, 12:26 PM
I tried finding reports of this issue a couple of times last week, didn't find anything similar enough so far 😕
s

Stylianos Gakis

03/06/2024, 12:27 PM
Yeah, I would suggest you file a new one
o

Oliver

03/06/2024, 12:27 PM
Wondering where exactly to file it. Is it for Google to fix or Jetbrains? 🤔
google 1
s

Stylianos Gakis

03/06/2024, 12:36 PM
Go here https://issuetracker.google.com/issues/new and find which component the BringIntoViewRequester is in and try to file it against that would be my first guess here. I know this may not be exactly a bug only involving that one, but hopefully it will be redirected to the right place if they determine it should be moved
s

Sean Proctor

03/06/2024, 11:53 PM
I don't think this is a bug. contentPadding is the padding around the part that is scrolling, so it can be scrolled off the screen an so shouldn't be considered when bringing an item into view. Can you handle focus manually and do something like:
Copy code
.onFocusChanged {
    if (it.isFocused) {
        scrollToItem(index, -topBarHeightPx)
    }
}
You'll need to check if the item is off the bottom or top of the list and set the offset appropriately. This is just an idea, totally untested.
a

Alex Vanyo

03/07/2024, 12:24 AM
s

Sean Proctor

03/07/2024, 12:31 AM
Do I misunderstand
contentPadding
? I imagine it as adding padding before the first item and after the last item.
s

Stylianos Gakis

03/07/2024, 7:58 AM
And horizontally too yes, but that doesn't change the fact that when you want to "bring it into view" as a result of a focus, you do want the content padding to be taken into consideration.
o

Oliver

03/09/2024, 9:07 PM
From what I gather,
contentPadding
should also represent the insets that obstruct the content. And due to the obstructions, the bring-into-view should take
contentPadding
into account.
Alex, thank you for the link. It seems it links to another issue, which seems to be more prioritised: https://issuetracker.google.com/issues/221252680 I added my 👍 to both, but also mentioned my use case in the one I linked. Guessing there is no point for me to create another issue.
4 Views