Add SearchScaffold.

This commit is contained in:
Thomas Andres Gomez 2022-05-02 08:54:12 +02:00
parent db7d6d8ab8
commit 98f0e94766
7 changed files with 254 additions and 21 deletions

View file

@ -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))
}
}

View file

@ -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

View file

@ -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) },
)
}
}

View file

@ -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

View file

@ -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()
}
}
}

View file

@ -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

View file

@ -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