Add SearchScaffold.
This commit is contained in:
parent
db7d6d8ab8
commit
98f0e94766
7 changed files with 254 additions and 21 deletions
|
|
@ -0,0 +1,93 @@
|
|||
package com.pixelized.biblib.ui.composable
|
||||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.biblib.R
|
||||
import com.pixelized.biblib.ui.scaffold.SearchScaffoldState
|
||||
import com.pixelized.biblib.ui.scaffold.rememberSearchScaffoldState
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.todo
|
||||
|
||||
|
||||
@Composable
|
||||
fun Search(
|
||||
modifier: Modifier = Modifier,
|
||||
state: SearchScaffoldState = rememberSearchScaffoldState(),
|
||||
avatar: Painter,
|
||||
onAvatar: () -> Unit = todo(),
|
||||
onSearch: () -> Unit = todo(),
|
||||
) {
|
||||
var test by remember { mutableStateOf("") }
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onSearch)
|
||||
.then(modifier),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(42.dp)
|
||||
.padding(horizontal = 8.dp),
|
||||
imageVector = Icons.Default.Search,
|
||||
tint = MaterialTheme.colors.onSurface,
|
||||
contentDescription = null
|
||||
)
|
||||
TextField(
|
||||
modifier = Modifier.weight(1f),
|
||||
label = {
|
||||
Text(
|
||||
color = MaterialTheme.colors.onSurface,
|
||||
text = "Rechercher sur BibLib"
|
||||
)
|
||||
},
|
||||
value = test,
|
||||
enabled = state.isCollapsed().not(),
|
||||
readOnly = state.isCollapsed(),
|
||||
colors = TextFieldDefaults.outlinedTextFieldColors(
|
||||
focusedBorderColor = Color.Transparent,
|
||||
unfocusedBorderColor = Color.Transparent,
|
||||
disabledBorderColor = Color.Transparent,
|
||||
),
|
||||
onValueChange = { test = it }
|
||||
)
|
||||
IconButton(
|
||||
modifier = Modifier.padding(horizontal = 8.dp),
|
||||
onClick = onAvatar,
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.clip(RoundedCornerShape(50)),
|
||||
painter = avatar,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_NO)
|
||||
@Preview(showBackground = true, uiMode = UI_MODE_NIGHT_YES)
|
||||
private fun SearchContentPreview() {
|
||||
BibLibTheme {
|
||||
Search(avatar = painterResource(R.drawable.ic_google))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.biblib.ui.navigation
|
||||
package com.pixelized.biblib.ui.scaffold
|
||||
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package com.pixelized.biblib.ui.scaffold
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateDp
|
||||
import androidx.compose.animation.core.updateTransition
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.ScrollState.Companion.Saver
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.Saver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
|
||||
@Composable
|
||||
fun SearchScaffold(
|
||||
modifier: Modifier = Modifier,
|
||||
state: SearchScaffoldState = rememberSearchScaffoldState(),
|
||||
topBar: @Composable () -> Unit,
|
||||
search: @Composable () -> Unit,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
var initialHeight by remember { mutableStateOf(0) }
|
||||
Layout(
|
||||
modifier = modifier,
|
||||
content = {
|
||||
val transition = updateTransition(
|
||||
label = "Collapse transition",
|
||||
targetState = state.isCollapsed()
|
||||
)
|
||||
val horizontal by transition.animateDp(label = "horizontal") {
|
||||
when (it) {
|
||||
true -> MaterialTheme.bibLib.dimen.medium
|
||||
else -> MaterialTheme.bibLib.dimen.default
|
||||
}
|
||||
}
|
||||
val vertical by transition.animateDp(label = "vertical") {
|
||||
when (it) {
|
||||
true -> MaterialTheme.bibLib.dimen.small
|
||||
else -> MaterialTheme.bibLib.dimen.default
|
||||
}
|
||||
}
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = horizontal, vertical = vertical)
|
||||
.layoutId("cardBox")
|
||||
) {
|
||||
Column {
|
||||
topBar()
|
||||
AnimatedVisibility(visible = state.isCollapsed().not()) {
|
||||
search()
|
||||
}
|
||||
}
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier.layoutId("contentBox")
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
) { measurables, constraints ->
|
||||
val cardBox = measurables.first { it.layoutId == "cardBox" }.measure(constraints)
|
||||
val contentBox = measurables.first { it.layoutId == "contentBox" }.measure(constraints)
|
||||
|
||||
layout(constraints.maxWidth, constraints.maxHeight) {
|
||||
if (initialHeight == 0) {
|
||||
initialHeight = cardBox.measuredHeight
|
||||
}
|
||||
contentBox.place(x = 0, y = initialHeight)
|
||||
cardBox.place(x = 0, y = 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberSearchScaffoldState(
|
||||
expended: Boolean = false
|
||||
): SearchScaffoldState {
|
||||
return rememberSaveable(saver = SearchScaffoldState.Saver) {
|
||||
SearchScaffoldState(expended = expended)
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
class SearchScaffoldState(
|
||||
expended: Boolean
|
||||
) {
|
||||
private var expended: Boolean by mutableStateOf(expended)
|
||||
|
||||
fun isCollapsed(): Boolean = expended.not()
|
||||
|
||||
fun expand() {
|
||||
expended = true
|
||||
}
|
||||
|
||||
fun collapse() {
|
||||
expended = false
|
||||
}
|
||||
|
||||
companion object {
|
||||
val Saver: Saver<SearchScaffoldState, Boolean> = Saver(
|
||||
save = { it.expended },
|
||||
restore = { SearchScaffoldState(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ import com.pixelized.biblib.ui.composable.SpannedText
|
|||
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
|
||||
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
|
||||
import com.pixelized.biblib.ui.composable.animation.Delay
|
||||
import com.pixelized.biblib.ui.navigation.LocalBottomDetailController
|
||||
import com.pixelized.biblib.ui.scaffold.LocalBottomDetailController
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.BookUio
|
||||
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
|
|
|
|||
|
|
@ -1,40 +1,68 @@
|
|||
package com.pixelized.biblib.ui.screen.home
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.pixelized.biblib.ui.navigation.BottomDetailScaffold
|
||||
import com.pixelized.biblib.ui.composable.Search
|
||||
import com.pixelized.biblib.ui.navigation.page.PageNavHost
|
||||
import com.pixelized.biblib.ui.scaffold.BottomDetailScaffold
|
||||
import com.pixelized.biblib.ui.scaffold.SearchScaffold
|
||||
import com.pixelized.biblib.ui.scaffold.SearchScaffoldState
|
||||
import com.pixelized.biblib.ui.scaffold.rememberSearchScaffoldState
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
accountViewModel: HomeViewModel = hiltViewModel(),
|
||||
navHostController: NavHostController = rememberNavController(),
|
||||
searchScaffoldState: SearchScaffoldState = rememberSearchScaffoldState(),
|
||||
) {
|
||||
|
||||
BottomDetailScaffold {
|
||||
Scaffold(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
SearchScaffold(
|
||||
state = searchScaffoldState,
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.clipToBounds(),
|
||||
topBar = {
|
||||
Column {
|
||||
HomeSearchBar()
|
||||
HomeTarBar(homePageNavController = navHostController)
|
||||
}
|
||||
Search(
|
||||
state = searchScaffoldState,
|
||||
avatar = accountViewModel.avatar,
|
||||
onSearch = {
|
||||
if (searchScaffoldState.isCollapsed()) {
|
||||
searchScaffoldState.expand()
|
||||
} else {
|
||||
searchScaffoldState.collapse()
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
search = {
|
||||
Box(modifier = Modifier.fillMaxSize())
|
||||
},
|
||||
content = {
|
||||
PageNavHost(
|
||||
modifier = Modifier.padding(it),
|
||||
navHostController = navHostController,
|
||||
)
|
||||
}
|
||||
Column {
|
||||
HomeTarBar(
|
||||
homePageNavController = navHostController
|
||||
)
|
||||
PageNavHost(
|
||||
modifier = Modifier.padding(it),
|
||||
navHostController = navHostController,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
BackHandler(searchScaffoldState.isCollapsed().not()) {
|
||||
searchScaffoldState.collapse()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import androidx.compose.material.MaterialTheme
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.pixelized.biblib.ui.navigation.LocalBottomDetailController
|
||||
import com.pixelized.biblib.ui.scaffold.LocalBottomDetailController
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.LazyBookThumbnailColumn
|
||||
import com.pixelized.biblib.ui.screen.home.page.news.NewsPage
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import androidx.compose.material.MaterialTheme
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.pixelized.biblib.ui.navigation.LocalBottomDetailController
|
||||
import com.pixelized.biblib.ui.scaffold.LocalBottomDetailController
|
||||
import com.pixelized.biblib.ui.screen.home.common.composable.LazyBookThumbnailColumn
|
||||
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||
import com.pixelized.biblib.utils.extention.bibLib
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue