Comments (6)
This workaround works for me:
@Composable
public fun CollapsingToolbarScaffold(
state: CollapsingToolbarScaffoldState,
modifier: Modifier = Modifier,
scrollStrategy: ScrollStrategy = ScrollStrategy.ExitUntilCollapsed,
enabled: Boolean = true,
toolbarModifier: Modifier = Modifier,
toolbar: @Composable CollapsingToolbarScope.() -> Unit,
content: @Composable BoxWithConstraintsScope.() -> Unit,
) {
var collapsable by remember { mutableStateOf(false) }
LaunchedEffect(collapsable) {
@OptIn(ExperimentalToolbarApi::class)
if (!collapsable) state.toolbarState.expand()
}
CollapsingToolbarScaffold(
modifier = modifier,
toolbarModifier = toolbarModifier,
state = state,
enabled = collapsable && enabled, // Force disable collapsing if it is not needed
scrollStrategy = scrollStrategy,
toolbar = toolbar,
body = {
var contentHeight by remember { mutableStateOf(0) }
BoxWithConstraints(Modifier.onGloballyPositioned { contentHeight = it.size.height }) {
collapsable = with(LocalDensity.current) {
val toolbarMaxOffset = state.toolbarState.maxHeight - state.toolbarState.minHeight
contentHeight > maxHeight.toPx() - toolbarMaxOffset
}
content()
}
},
)
}
UPD: Simplified workaround
Look at the first version of workaround
@Composable
public fun CollapsingToolbarScaffold(
state: CollapsingToolbarScaffoldState,
modifier: Modifier = Modifier,
scrollStrategy: ScrollStrategy = ScrollStrategy.ExitUntilCollapsed,
enabled: Boolean = true,
toolbarModifier: Modifier = Modifier,
toolbar: @Composable CollapsingToolbarScope.() -> Unit,
content: @Composable CollapsingToolbarContentScope.() -> Unit,
) {
CollapsingToolbarScaffold(
modifier = modifier,
toolbarModifier = toolbarModifier,
state = state,
enabled = enabled,
scrollStrategy = scrollStrategy,
toolbar = toolbar,
body = {
var contentHeight by remember { mutableStateOf(0) }
BoxWithConstraints(Modifier.onGloballyPositioned { contentHeight = it.size.height }) {
CollapsingToolbarContentScopeImpl(
scope = this,
density = LocalDensity.current,
toolbarOffset = state.toolbarState.maxHeight - state.toolbarState.minHeight,
contentHeightPx = contentHeight,
).content()
}
},
)
}
@Stable
public interface CollapsingToolbarContentScope : BoxWithConstraintsScope {
/** The content height in [Dp]. */
public val contentHeight: Dp
/** The max height that may fit without toolbar collapsing. */
public val maxHeightWhenExpanded: Dp
/** Returns `true` if content can not fit on screen without toolbar collapsing. */
public val collapsingNeeded: Boolean
}
private data class CollapsingToolbarContentScopeImpl(
private val scope: BoxWithConstraintsScope,
private val density: Density,
private val toolbarOffset: Int,
private val contentHeightPx: Int,
) : CollapsingToolbarContentScope, BoxWithConstraintsScope by scope {
override val contentHeight: Dp
get() = with(density) { contentHeightPx.toDp() }
override val maxHeightWhenExpanded: Dp
get() = maxHeight - with(density) { toolbarOffset.toDp() }
override val collapsingNeeded: Boolean
get() = contentHeight > maxHeightWhenExpanded
}
With this you can disable scrolling and make toolbar always expanded if content fits on the screen looking at collapsingNeeded flag in CollapsingToolbarContentScope:
val state = rememberCollapsingToolbarScaffoldState()
CollapsingToolbarScaffold(
state = state,
toolbar = { /* Toolbar content here */ }
) {
LaunchedEffect(collapsingNeeded) {
// We don't want the state when scroll is disabled but toolbar is not expanded
@OptIn(ExperimentalToolbarApi::class)
if (!collapsingNeeded) state.toolbarState.expand()
}
Column(
// Disable scrolling if content fits on screen
modifier = Modifier.verticalScroll(rememberScrollState(), enabled = collapsingNeeded),
) {
// Content here
}
}
from compose-collapsing-toolbar.
I looked into the behavior of androidx's CollapsingToolbarLayout, looks like it collapses only if the height of a body layout is large enough to scroll which is different from the current behavior of my library.
One point I want to think of is when the height of the body layout is somewhere between body hole + collapsed toolbar
and body hole + expanded toolbar
. AndroidX leaves some space if the actual height of body layout is smaller than that of body hole, maybe I could give some options to choose this behavior?
from compose-collapsing-toolbar.
Thank you for so quick response.
Yes, in CollapsingToolbarLayout it checks if the content height is more than the screen height and only then make it collapsable when scrolling.
In your library it scrolls and collapse always.
Sorry but I didn't get your question:
AndroidX leaves some space if the actual height of body layout is smaller than that of body hole, maybe I could give some options to choose this behavior?
Could you please rephrase it ?
from compose-collapsing-toolbar.
Is there any workaround for this case? For example disable vertical scroll if content fits to screen. But how to detect "if content fits"?
from compose-collapsing-toolbar.
I meant the edge case where the body content's height is not tall enough to cover the whole screen when the toolbar is collapsed but it fills the screen when toolbar is expanded.
By the way, I didn't tested myself though did you try calculating available height with CollapsingToolbarState.maxHeight
as a workaround?
from compose-collapsing-toolbar.
Hi, I have already created PR for this: #85
By the way, if you want to use this feature, I created a separated remote dependency, while this PR is under review:
Add it in your root build.gradle at the end of repositories:
all projects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Step 2. Add the dependency
dependencies {
implementation 'com.github.GIGAMOLE:ComposeCollapsingToolbar:latest-version'
}
Or you can simply download it from there:
https://github.com/GIGAMOLE/ComposeCollapsingToolbar/releases
from compose-collapsing-toolbar.
Related Issues (20)
- Retain offset/progress when toolbar's height is changed
- toolbar doesn't stay fully open when the screen is opened HOT 1
- Wrong initial scroll position when toolbar has dynamic height HOT 2
- Always visible toolbar navigation icon?
- ExitUntilCollapsed strategy does not set OffsetY in ScrollStrategy HOT 1
- SwipeRefresh as a child doesn't expand HOT 1
- Toolbar height remember issue
- How to use the pin modifier with ScrollStrategy.EnterAlways?
- Is it possible to hide the toolbar only by a set height? HOT 1
- Not able Collabs tool bar manully
- Is it possible to change the expanded state by scrolling the toolbar area?
- Feature of jumping between states expanded/collapsed HOT 1
- Full HOT 1
- Cash App $URL Change!
- Used without consent HOT 2
- Is the library still maintained?
- I have a way to deal with it temporarily
- Collapsing did not show screen bottom and did not scroll top
- CollapsingToolbarScaffold's body height is incorrect when restored from saved state with `ExitUntilCollapsed` scrolling strategy HOT 2
- Carl H. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from compose-collapsing-toolbar.