Improve pull down scaffold performance
This commit is contained in:
parent
f2fe8a6ce9
commit
98da9ea042
@ -235,7 +235,7 @@ fun PagerScaffold(
|
|||||||
.padding(start = 8.dp, end = 8.dp, bottom = 8.dp)
|
.padding(start = 8.dp, end = 8.dp, bottom = 8.dp)
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.offset(y = widgetEditModeOffset),
|
.offset(y = widgetEditModeOffset),
|
||||||
level = searchBarLevel, focused = focusSearchBar, onFocusChange = {
|
level = { searchBarLevel }, focused = focusSearchBar, onFocusChange = {
|
||||||
if (it) viewModel.openSearch()
|
if (it) viewModel.openSearch()
|
||||||
viewModel.setSearchbarFocus(it)
|
viewModel.setSearchbarFocus(it)
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
package de.mm20.launcher2.ui.launcher
|
package de.mm20.launcher2.ui.launcher
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.util.Log
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.slideIn
|
import androidx.compose.animation.slideIn
|
||||||
import androidx.compose.animation.slideOut
|
import androidx.compose.animation.slideOut
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.gestures.LocalOverScrollConfiguration
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
@ -25,18 +29,14 @@ import androidx.compose.ui.graphics.graphicsLayer
|
|||||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.IntSize
|
|
||||||
import androidx.compose.ui.unit.Velocity
|
import androidx.compose.ui.unit.Velocity
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import com.google.accompanist.pager.VerticalPager
|
|
||||||
import com.google.accompanist.pager.calculateCurrentOffsetForPage
|
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
import com.google.accompanist.pager.rememberPagerState
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||||
@ -48,9 +48,9 @@ import de.mm20.launcher2.ui.launcher.search.SearchColumn
|
|||||||
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
import de.mm20.launcher2.ui.launcher.search.SearchVM
|
||||||
import de.mm20.launcher2.ui.launcher.widgets.WidgetColumn
|
import de.mm20.launcher2.ui.launcher.widgets.WidgetColumn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
@OptIn(ExperimentalPagerApi::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PullDownScaffold(
|
fun PullDownScaffold(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@ -129,7 +129,7 @@ fun PullDownScaffold(
|
|||||||
LaunchedEffect(isSearchOpen) {
|
LaunchedEffect(isSearchOpen) {
|
||||||
if (isSearchOpen) searchScrollState.scrollTo(0)
|
if (isSearchOpen) searchScrollState.scrollTo(0)
|
||||||
if (!isSearchOpen) searchVM.search("")
|
if (!isSearchOpen) searchVM.search("")
|
||||||
pagerState.animateScrollToPage(if (isSearchOpen) 1 else 0)
|
//pagerState.animateScrollToPage(if (isSearchOpen) 1 else 0)
|
||||||
searchBarOffset.animateTo(0f)
|
searchBarOffset.animateTo(0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,79 +198,88 @@ fun PullDownScaffold(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var size by remember { mutableStateOf(IntSize.Zero) }
|
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.onSizeChanged {
|
.clipToBounds()
|
||||||
size = it
|
.nestedScroll(nestedScrollConnection)
|
||||||
}
|
|
||||||
.offset { IntOffset(0, offsetY.value.toInt()) },
|
.offset { IntOffset(0, offsetY.value.toInt()) },
|
||||||
contentAlignment = Alignment.TopCenter
|
contentAlignment = Alignment.TopCenter
|
||||||
) {
|
) {
|
||||||
VerticalPager(
|
|
||||||
state = pagerState,
|
BoxWithConstraints(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.nestedScroll(nestedScrollConnection),
|
.fillMaxSize()
|
||||||
count = 2,
|
|
||||||
reverseLayout = true,
|
|
||||||
userScrollEnabled = false,
|
|
||||||
) {
|
) {
|
||||||
if (it == 1) {
|
val height by remember {
|
||||||
val websearches by searchVM.websearchResults.observeAsState(emptyList())
|
derivedStateOf { maxHeight }
|
||||||
val webSearchPadding by animateDpAsState(
|
}
|
||||||
if (websearches.isEmpty()) 0.dp else 48.dp
|
Log.d("MM20", "PullDownScaffold recompose, $maxHeight")
|
||||||
)
|
CompositionLocalProvider(
|
||||||
val offset = calculateCurrentOffsetForPage(1).absoluteValue
|
LocalOverScrollConfiguration provides null
|
||||||
SearchColumn(
|
) {
|
||||||
|
val offset by animateFloatAsState(if (isSearchOpen) 1f else 0f)
|
||||||
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.graphicsLayer {
|
.fillMaxWidth()
|
||||||
transformOrigin = TransformOrigin.Center
|
.requiredHeight(height * 2)
|
||||||
scaleX = 1 - offset
|
.offset {
|
||||||
scaleY = 1 - offset
|
IntOffset(
|
||||||
alpha = 1 - offset
|
0,
|
||||||
|
((-0.5f + offset) * height.toPx()).roundToInt()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.fillMaxSize()
|
) {
|
||||||
.verticalScroll(searchScrollState)
|
|
||||||
.padding(8.dp)
|
val websearches by searchVM.websearchResults.observeAsState(emptyList())
|
||||||
.padding(top = 56.dp)
|
val webSearchPadding by animateDpAsState(
|
||||||
.padding(top = webSearchPadding)
|
if (websearches.isEmpty()) 0.dp else 48.dp
|
||||||
.imePadding()
|
)
|
||||||
)
|
SearchColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.graphicsLayer {
|
||||||
|
transformOrigin = TransformOrigin.Center
|
||||||
|
scaleX = offset
|
||||||
|
scaleY = offset
|
||||||
|
alpha = offset
|
||||||
|
}
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height)
|
||||||
|
.verticalScroll(searchScrollState)
|
||||||
|
.padding(8.dp)
|
||||||
|
.padding(top = 56.dp)
|
||||||
|
.padding(top = webSearchPadding)
|
||||||
|
.imePadding()
|
||||||
|
)
|
||||||
|
val editModePadding by animateDpAsState(if (isWidgetEditMode) 56.dp else 0.dp)
|
||||||
|
WidgetColumn(
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.graphicsLayer {
|
||||||
|
transformOrigin = TransformOrigin.Center
|
||||||
|
scaleX = 1 - offset
|
||||||
|
scaleY = 1 - offset
|
||||||
|
alpha = 1 - offset
|
||||||
|
}
|
||||||
|
.fillMaxWidth()
|
||||||
|
.requiredHeight(height)
|
||||||
|
.verticalScroll(widgetsScrollState)
|
||||||
|
.padding(8.dp)
|
||||||
|
.padding(top = editModePadding),
|
||||||
|
clockHeight = { height },
|
||||||
|
editMode = isWidgetEditMode,
|
||||||
|
onEditModeChange = {
|
||||||
|
viewModel.setWidgetEditMode(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it == 0) {
|
|
||||||
val offset = calculateCurrentOffsetForPage(0).absoluteValue
|
|
||||||
val editModePadding by animateDpAsState(if (isWidgetEditMode) 56.dp else 0.dp)
|
|
||||||
val clockHeight by remember {
|
|
||||||
derivedStateOf {
|
|
||||||
with(density) {
|
|
||||||
size.height.toDp()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WidgetColumn(
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.graphicsLayer {
|
|
||||||
transformOrigin = TransformOrigin.Center
|
|
||||||
scaleX = 1 - offset
|
|
||||||
scaleY = 1 - offset
|
|
||||||
alpha = 1 - offset
|
|
||||||
}
|
|
||||||
.fillMaxSize()
|
|
||||||
.verticalScroll(widgetsScrollState)
|
|
||||||
.padding(8.dp)
|
|
||||||
.padding(top = editModePadding),
|
|
||||||
clockHeight = { clockHeight },
|
|
||||||
editMode = isWidgetEditMode,
|
|
||||||
onEditModeChange = {
|
|
||||||
viewModel.setWidgetEditMode(it)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AnimatedVisibility(visible = isWidgetEditMode,
|
AnimatedVisibility(visible = isWidgetEditMode,
|
||||||
enter = slideIn { IntOffset(0, -it.height) },
|
enter = slideIn { IntOffset(0, -it.height) },
|
||||||
exit = slideOut { IntOffset(0, -it.height) }
|
exit = slideOut { IntOffset(0, -it.height) }
|
||||||
@ -304,11 +313,10 @@ fun PullDownScaffold(
|
|||||||
)
|
)
|
||||||
|
|
||||||
SearchBar(
|
SearchBar(
|
||||||
level = searchBarLevel,
|
level = { searchBarLevel },
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
.clipToBounds()
|
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.offset { IntOffset(0, searchBarOffset.value.toInt()) }
|
.offset { IntOffset(0, searchBarOffset.value.toInt()) }
|
||||||
.offset(y = editModeSearchBarOffset),
|
.offset(y = editModeSearchBarOffset),
|
||||||
|
|||||||
@ -57,7 +57,7 @@ import java.io.File
|
|||||||
@Composable
|
@Composable
|
||||||
fun SearchBar(
|
fun SearchBar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
level: SearchBarLevel,
|
level: () -> SearchBarLevel,
|
||||||
focused: Boolean,
|
focused: Boolean,
|
||||||
onFocusChange: (Boolean) -> Unit,
|
onFocusChange: (Boolean) -> Unit,
|
||||||
reverse: Boolean = false,
|
reverse: Boolean = false,
|
||||||
@ -94,7 +94,7 @@ fun SearchBar(
|
|||||||
|
|
||||||
SearchBar(
|
SearchBar(
|
||||||
modifier,
|
modifier,
|
||||||
level,
|
level(),
|
||||||
websearches,
|
websearches,
|
||||||
value = query,
|
value = query,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user