I'm using Jetpack compose with Scaffold. As you can see it doesn't work properly.
Scaffold(
modifier = Modifier
.fillMaxSize()
.navigationBarsPadding(),
) {
...
}
Note that I have called WindowCompat.setDecorFitsSystemWindows(window, false) on host activity.
Also this result is happing on Lg G4 - Api 26
You can try add this code, set in your root
ProvideWindowInsets {}
WindowCompat.setDecorFitsSystemWindows(window, false) :Indicates that the content can extend to the system bar
In your case, you can use:WindowCompat.setDecorFitsSystemWindows(window, true)
Example:
Scaffold(
modifier = Modifier
.fillMaxSize(),
) {
...
}
Related
working on an edge2edge display app, i came across a situation about scaffold, according to the official doc, the scaffold padding values are used to offset the top and bottom bars, if they exist. Turns out that when i use scaffold without providing top/bottom parameter, the contents of the scaffold are padded at the top & bottom automatically with blank space
If i provide a parameter for either the topBar or bottomBar, the other gets automatically filled with blank space.
Catch : This only happens when WindowCompat.setDecorFitsSystemWindows(window, false) is used
Code Snippet:
WindowCompat.setDecorFitsSystemWindows(window, false) //commenting this line of code gives desired results but defeates the E2E display
setContent {
TestTheme {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Cyan)
) {
Scaffold(
modifier = Modifier
.fillMaxSize(0.8f)
.align(Alignment.Center),
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
.background(Color.White)
) {
Log.d("scaffold", "padding values = $paddingValues")
Text("Android")
}
}
}
}
}
not commented : ------ commented :
-----
Q : Pls, what is the reason for this behaviour, & how can i achieve a working E2E with the scaffold not adding the unnecessary paddings?
Developing tools :
Lastest Android Studio(Electric Eel)
androidx.compose.material3
When I don't use the following code, it is displayed on the page.
#SuppressLint("UnusedMaterialScaffoldPaddingParameter")
You should use the PaddingValues of the Scaffold because these values are calculated based on the other items inside of your scaffold. For instance when you use a topBar or BottomBar, your screen will be partially covered with the UI element. When you use the PaddingValues inside the content of your scaffold this won't happen. You can use de PaddingValues like this:
Scaffold(
topBar = {
// some TopBar
},
bottomBar = {
// some BottomBar
},
) { paddingValues ->
Box(
modifier = Modifier.padding(bottom = paddingValues.calculateBottomPadding(), top = paddingValues.calculateTopPadding())
) {
// your UI
}
}
I use Jetpack Compose in a Android Studio project, the code A can work well, but I get the following warning information, why ?
"Modifier parameter should be named modifier"
Code A
#Composable
fun ScreenAbout(
rootModifier: Modifier = Modifier,
onBack: () -> Unit,
scaffoldState: ScaffoldState = rememberScaffoldState()
) {
Scaffold(
modifier = rootModifier.fillMaxSize(),
scaffoldState = scaffoldState,
topBar = { AboutAppBar(onBack = onBack) }
) { paddingValues ->
Column(
...
}
There is Link Check.
It checks Composable functions with Modifiers parameters for consistency with guidelines.
For functions with one / more modifier parameters, the first modifier parameter must:
Be named modifier
Have a type of Modifier
Either have no default value, or have a default value of Modifier
If optional, be the first optional parameter in the parameter list
In you case just use:
#Composable
fun ScreenAbout(
modifier: Modifier = Modifier,
Or if you want to suppress the warning add
#SuppressLint("ModifierParameter")
#Composable
fun ScreenAbout(
rootModifier: Modifier = Modifier,
I was playing around with Jetpack Compose TextField and I found one strange behaviour with Keyboard.
If my TextField is around bottom of the screen and I open keyboard, the TextField is remain hidden behind the keyboard.
I tried some solutions as well.
Modifying android:windowSoftInputMode="adjustPan" and android:windowSoftInputMode="adjustResize"
If I use adjustPan, sometimes TextField is lifted up with the Keyboard but sometimes it does not.
Here is the code and images of what is happening.
Ok I did something that worked for me, I clarify that I have only been learning compose for a few weeks so don't expect much from me, I simply did something that may not be the right way but it is functional for me and may be useful to anyone.
What I did was create a main class that inherits the ComponentActivity() with all the toys.
class Login : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HealthAtHansClientTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
LoginLayout()
}
}
}
}
}
After that I imported my #Composable function which contained my layout with the LoginLayout, but the important part is this:
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(bottom = 100.dp, end = 40.dp, start = 40.dp)
.verticalScroll(scrollState),
verticalArrangement = Arrangement.SpaceAround,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 30.dp)
) {
Text(text = "Hola !", style = TextStyle(fontSize = 40.sp))
}
Row(horizontalArrangement = Arrangement.Center) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
TextField(
maxLines = 1,
modifier = Modifier.fillMaxWidth(),
value = documentNumber,
onValueChange = { documentNumber = it })
Spacer(modifier = Modifier.height(100.dp))
TextField(
maxLines = 1,
modifier = Modifier.fillMaxWidth(),
value = privateCode,
onValueChange = { privateCode = it })
}
}
}
Note that the space between the Textfields is 100 this was just to test that it is functional.
and finally declare the Login class in my main activity in the following way, since the Mainactivity came by default but it was only for this test, the idea is only that they realize the line that I added
And voilà that was all now my TextField is not hidden, I think it would be very feasible if you have extensive forms you create your "activity" in the manifest and add the line android:windowSoftInputMode="adjustResize"
that way the problem is over.
I hope someone with more skill and knowledge can do something more efficient, for now it works for me.
If there is already a more efficient solution for that, the comment is appreciated, if my solution is stupid, I would appreciate feedback to learn.
One other thing that happens is that if you run the emulator with 'DefaultPreview', none of the ways I try to do it work.
If you run the emulation of your application in App, it works without problem.
But I wanted to go further, so I compiled this example in a release apk version where it is supposed to look like it should and it works perfectly as you can see in the image.
Update at October 2022: The following code does the trick:
class SampleActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
setContent {
LazyColumn(
contentPadding = WindowInsets.navigationBars.asPaddingValues()
) {
// items
}
}
}
}
Setting Activity to fit system windows and also using contentPadding is key here.
In Jetpack compose 1.0.0-beta01, I am calling the BottomSheetScaffold like this:
BottomSheetScaffold(
scaffoldState = bottomSheetScaffoldState,
sheetContent = { Text("") },
sheetShape = Shapes.large,
backgroundColor = AppTheme.colors.uiBackground,
modifier = modifier
) { (content) }
... and getting the following error:
java.lang.IllegalArgumentException: The initial value must have an associated anchor.
Any tips on fixing this?
Don't forget to add the following atribute:
sheetPeekHeight = 0.dp
So your code should be like this:
BottomSheetScaffold(
scaffoldState = bottomSheetScaffoldState,
sheetContent = { Text("") },
sheetShape = Shapes.large,
sheetPeekHeight = 0.dp, // <--- new line
backgroundColor = AppTheme.colors.uiBackground,
modifier = modifier
) { (content) }
When bottomSheetState is expand, sheetContent must have real content to show.
You need check this.
I got the same issue when using ModalBottomSheetLayout, and my compose material version is 1.2.0-rc02
androidx.compose.material:material:1.2.0-rc02
I want to show the bottom modal when one item is selected, and if no item is selected, the modal should be empty.
ModalBottomSheetLayout(
sheetState = modalBottomSheetState,
sheetContent = {
EditProgressContent(book = book)
}
) { ... }
#Composable
fun EditProgressContent(book: Book?) {
if (book == null) return
Text(book.title)
}
When book is null, I got the same crash. There is no peekHeight parameter for ModalBottomSheetLayout, so I have to add a pixel when book is null
#Composable
fun EditProgressContent(book: Book?) {
if (book == null) {
Box(modifier = Modifier.size(1.dp)
return
}
Text(book.title)
}
The code looks silly, hope it can be fixed from Google.
In case you end up on this page because you use the BackdropScaffold, the suggested solution does the trick as well. Simply set the peekHeight.
For example like this:
BackdropScaffold(
appBar = {},
backLayerContent = {},
frontLayerContent = {},
peekHeight = 0.dp
)
Then Preview works like a charm again.
Fun fact though: Don't set it to 56.dp which is the default init value it normally should be initialised with (value of BackdropScaffoldDefaults.PeekHeight). 56.dp results in the anchor rendering problem in my current setup.
(Using compose version '1.1.1')
On new version, this error happens when the initial State is Expanded, where try to open the Modal before launched. Try launcher via ModalBottomSheetState from LaunchedEffect (maybe can need a delay)