Create full screen bottomsheets with bottomBar in jetpack compose - android

I do have a requirement in jetpack compose where I need a bottom bar in my scaffold also a bottom sheet with adjustable height. I can achieve only any one of these.
I had to sacrifice the bottom bar with below code:
BottomSheetScaffold(sheetContent = {//anything here})
{ innerPadding -> Box(){}
}
I have no option to use bottom bar here whereas I have the freedom to adjust the height of the sheet. The second solution is using ModalBottomSheetLayout where I can add scaffold inside it and add bottom bar but won't be able to adjust the height of sheet.
ModalBottomSheetLayout(
sheetState = modalBottomSheetState,
sheetContent = {//anything here}
){
Scaffold(
topBar = {
//
},
bottomBar = {
//
},
){
innerPadding -> Box(){}
}
}

Your problem can be possibly solved with BottomSheetScaffold. You can adjust its height in closed position via sheetPeekHeight. To have a bottombar element when the bottom sheet is collapsed, you should read this article and take a look at the related sample. The principle of this solution is to animate the contents of the bottom sheet to bottom bar when it's collapsed, and to animate to the content you want in your bottom sheet when it's opened.
the article that explains the solution, and the sample.
If that doesn't work for you, then you should probably look at your own composable realisation. The requirements for implementing bottom sheet-like functionality are: nestedScroll, swipeable and offset Modifier extensions. How to deal with them you can find here: article about nested scrolling and bottom sheets.

Related

Multiple BottomSheet in one Screen in Jetpack Compose

As from ModalBottomSheetLayout doc we have to provide content. If i want to add multiple BottomSheet to a Screen i can't use multiple ModalBottomSheetLayout as same content have to pass multiple times and it will not work.
After searching i have found many are using multiple sheetContent in a single ModalBottomSheetLayout. Just like below way:
sheetContent = {
when (sheetContentState.value) {
0 -> {
BottomSheetFirstScreen()
}
1 -> {
BottomSheetSecondScreen()
}
}
}
For me it become complex as different Sheet configuration using same code. I want to know is there any other better way to load multiple BottomSheet in a Screen.
How about using ModalBottomSheetLayout and BottomSheetScaffold in a single Screen. How to do that.
Thanks in advance.

In Jetpack Compose, Is there a way to make swipeable rows work better inside a scrollable LazyColumn?

I have LazyColumn that has verticalScroll modifier, and each child row also has a horizontal swipeable modifier. Everything actually works pretty well, but there is a bit of a problem when trying to scroll vertically -- if there's even a very slight horizontal movement, then the vertical scroll doesn't get triggered, and the horizontal swipe is triggered instead.
Is there any way to set a 'preference' for the vertical scroll, so that if there's any vertical movement, then the swipe shouldn't happen?
Edit:
I should clarify that I'm using the swipeable modifier on each row for swipe-to-dismiss functionality. It's got some custom functionality, which is why I'm not using the SwipeToDismiss() composable, but I did try running it using SwipeToDismiss(), and it has the same problem
I suggest using HorizontalPager() inside your verticalScroll Column.
Column(
Modifier
.verticalScroll(scrollState)
) {
HorizontalPager(/*...*/)
}
It is smooth by default but you can even modify the gesture of it by changing flingBehavour as described here:
Swipe sensitivity for HorizontalPager in Compose

Android Compose webview is stretched

I want to create with Jetpack Compose a dinamic header that should resize when user scrolls on the main screen content section. The dynamic header works fine, but I have some problem with a WebView.: with Compose when the WebView is rendered, it is stretched and any popup shown to the user are out of the main viewport.
This is an implementation using the old-style XML layout:
We have on the top the fake green dynamic header. The webview is loaded with an initial popup centered into the available screen, as expected.
With compose, the result is the following:
On the top there is the fake gray dynamic header, but the webview is "stretched", and the initial popup is not centered.
This happens also with a stand-alone WebView, without the dynamic header on top, so this is not an issue created by the dynamic header.
The implementation of the WebView is pretty simple
#SuppressLint("SetJavaScriptEnabled")
#Composable
fun PageBodyWithWebView(
scrollState: ScrollState,
) {
val context = LocalContext.current
AndroidView(
modifier = Modifier
.verticalScroll(scrollState)
.fillMaxWidth()
.fillMaxHeight(),
factory = {
WebView(context).apply {
settings.javaScriptEnabled = true
loadUrl(pageUrl)
}
})
}
So what is wrong with this? How we can center the webview, so the user can see all the popup as expected?
The base issue is that you're not reading the scroll from the WebView, and the scroll modifier on the AndroidView composable is not doing what you think it does. A solution is to hoist an event when the webview is scrolled and respond to that: https://gist.github.com/rock3r/65642c73de8602ac40a340c84e20b16a

Android sticky - footer using jetpack compose: Align footer view to table, until it reaches screen size and then become fixed at the bottom

I want to achieve this using jetpack compose.
A is scrollable list of row items. When A is smaller than screen(or parent) size, B(footer) should be placed bellow the last row. When A + B are bigger than screen size, then B becomes fixed at the bottom and A content is scrollable. I'm wondering if there is easy way to achieve this, using compose ConstraintLayout.
I found solution for it. I had to use Modifier.weight(1f, false) at A.
There are many ways to do this but the most efficient way is to use the bottomBar property of Scaffold View.
For example:
#Composable
fun RenderContent() {
Scaffold(
topBar = { /* Your app bar goes here */ },
bottomBar = { /* Anything you place in here will be stick to the bottom. */ }
) {
// ... Rest of the content
// Benefits: If you make the content scrollable and
// the `bottomBar` composable remain on top of the content
}
}
If I understood you correctly you are trying to add a footer view to a LazyColmn. The LazyColumn in JetpackCompose is behaving like the native ListView. I will give an example of a LazyColumn that has a view(composable) at the bottom that is shown when you scroll at the end of the list:
LazyColumn() {
item {
//If you want the first item to stay always on top as you scroll use stickyHeader for this section.
Text("This is the first item")
}
items(listItems.size) {
Text("This is a normal list item")
}
item {
Text("This item will behave as a footer and display at the end of the list")
}
}
Hope this helps somebody.
Thanks

Android Standard Bottom Sheet with animated toolbar when sheet expanded

I have a fragment, within that fragment I want to display a standard bottom sheet. When the sheet is expanded Id like to display a toolbar at the top of the sheet, with close/collapse button, something like presented on https://material.io/components/sheets-bottom#behavior under Behaviour -> Visibility -> FullScreen
To my surprise Im struggling to achieve similar effect - tried applying different scroll flags (app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed") however Im getting opposite results - toolbar is visible when sheet is half extended and disappars when I scroll the sheet to the top.

Categories

Resources