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.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.PaddingValues 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.AnimatedDelayer
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
import com.pixelized.biblib.ui.composable.animation.Delay 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.BookUio
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme

View file

@ -1,40 +1,68 @@
package com.pixelized.biblib.ui.screen.home package com.pixelized.biblib.ui.screen.home
import androidx.compose.foundation.layout.Column import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.background
import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.*
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier 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.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController 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.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) @OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
fun HomeScreen( fun HomeScreen(
accountViewModel: HomeViewModel = hiltViewModel(), accountViewModel: HomeViewModel = hiltViewModel(),
navHostController: NavHostController = rememberNavController(), navHostController: NavHostController = rememberNavController(),
searchScaffoldState: SearchScaffoldState = rememberSearchScaffoldState(),
) { ) {
BottomDetailScaffold { BottomDetailScaffold {
Scaffold( SearchScaffold(
modifier = Modifier.systemBarsPadding(), state = searchScaffoldState,
modifier = Modifier
.systemBarsPadding()
.clipToBounds(),
topBar = { topBar = {
Column { Search(
HomeSearchBar() state = searchScaffoldState,
HomeTarBar(homePageNavController = navHostController) avatar = accountViewModel.avatar,
} onSearch = {
if (searchScaffoldState.isCollapsed()) {
searchScaffoldState.expand()
} else {
searchScaffoldState.collapse()
}
}
)
},
search = {
Box(modifier = Modifier.fillMaxSize())
}, },
content = { content = {
PageNavHost( Column {
modifier = Modifier.padding(it), HomeTarBar(
navHostController = navHostController, 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.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel 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.common.composable.LazyBookThumbnailColumn
import com.pixelized.biblib.ui.screen.home.page.news.NewsPage import com.pixelized.biblib.ui.screen.home.page.news.NewsPage
import com.pixelized.biblib.ui.theme.BibLibTheme 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.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel 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.common.composable.LazyBookThumbnailColumn
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib import com.pixelized.biblib.utils.extention.bibLib