improve scrolling
This commit is contained in:
parent
93aac4c617
commit
8db96078d2
3 changed files with 62 additions and 25 deletions
|
@ -60,9 +60,6 @@ private fun PersonDetailsScreen(
|
|||
person: Assignment?,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
) {
|
||||
// Activate scrolling
|
||||
LocalView.current.requestFocus()
|
||||
|
||||
MaterialTheme {
|
||||
Scaffold(
|
||||
vignette = {
|
||||
|
@ -70,11 +67,15 @@ private fun PersonDetailsScreen(
|
|||
Vignette(vignettePosition = VignettePosition.Bottom)
|
||||
}
|
||||
},
|
||||
positionIndicator = { PositionIndicator(scrollState = scrollState) }
|
||||
positionIndicator = {
|
||||
if (person != null) {
|
||||
PositionIndicator(scrollState = scrollState)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.scrollHandler(scrollState)
|
||||
.rotaryEventHandler(scrollState)
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = if (LocalConfiguration.current.isScreenRound) 18.dp else 8.dp)
|
||||
.verticalScroll(scrollState),
|
||||
|
|
|
@ -13,19 +13,20 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
|
@ -36,9 +37,13 @@ import androidx.wear.compose.material.Button
|
|||
import androidx.wear.compose.material.ButtonDefaults
|
||||
import androidx.wear.compose.material.Card
|
||||
import androidx.wear.compose.material.MaterialTheme
|
||||
import androidx.wear.compose.material.PositionIndicator
|
||||
import androidx.wear.compose.material.Scaffold
|
||||
import androidx.wear.compose.material.ScalingLazyColumn
|
||||
import androidx.wear.compose.material.ScalingLazyListState
|
||||
import androidx.wear.compose.material.Text
|
||||
import androidx.wear.compose.material.Vignette
|
||||
import androidx.wear.compose.material.VignettePosition
|
||||
import androidx.wear.compose.material.rememberScalingLazyListState
|
||||
import coil.annotation.ExperimentalCoilApi
|
||||
import coil.compose.rememberImagePainter
|
||||
|
@ -65,30 +70,50 @@ fun PersonListScreen(
|
|||
people: List<Assignment>?,
|
||||
personSelected: (person: Assignment) -> Unit,
|
||||
issMapClick: () -> Unit,
|
||||
scrollState: ScalingLazyListState = rememberScalingLazyListState(),
|
||||
) {
|
||||
MaterialTheme {
|
||||
AnimatedVisibility(
|
||||
visible = people != null,
|
||||
enter = slideInVertically()
|
||||
) {
|
||||
if (people != null) {
|
||||
if (people.isNotEmpty()) {
|
||||
PersonList(people, personSelected, issMapClick)
|
||||
} else {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Card(
|
||||
onClick = { },
|
||||
modifier = Modifier.testTag(NoPeopleTag)
|
||||
) {
|
||||
Text("No people in space!")
|
||||
}
|
||||
Scaffold(
|
||||
vignette = {
|
||||
if (!people.isNullOrEmpty()) {
|
||||
Vignette(VignettePosition.Bottom)
|
||||
}
|
||||
},
|
||||
positionIndicator = {
|
||||
if (!people.isNullOrEmpty()) {
|
||||
PositionIndicator(scrollState)
|
||||
}
|
||||
}
|
||||
) {
|
||||
if (people.isNullOrEmpty()) {
|
||||
EmptyPersonList()
|
||||
} else {
|
||||
PersonList(people, personSelected, issMapClick, scrollState)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EmptyPersonList() {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Card(
|
||||
onClick = {},
|
||||
modifier = Modifier.testTag(NoPeopleTag)
|
||||
) {
|
||||
Text("No people in space!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PersonList(
|
||||
people: List<Assignment>,
|
||||
|
@ -96,14 +121,18 @@ fun PersonList(
|
|||
issMapClick: () -> Unit,
|
||||
scrollState: ScalingLazyListState = rememberScalingLazyListState(),
|
||||
) {
|
||||
// Activate scrolling
|
||||
LocalView.current.requestFocus()
|
||||
val configuration = LocalConfiguration.current
|
||||
// extra content padding to prevent bottom item from crop
|
||||
val extraBottomPadding = remember {
|
||||
if (configuration.isScreenRound) 40.dp else 0.dp
|
||||
}
|
||||
|
||||
ScalingLazyColumn(
|
||||
modifier = Modifier
|
||||
.testTag(PersonListTag)
|
||||
.scrollHandler(scrollState),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
.rotaryEventHandler(scrollState)
|
||||
.padding(horizontal = 4.dp),
|
||||
contentPadding = PaddingValues(start = 8.dp, top = 8.dp, end = 8.dp, bottom = 8.dp + extraBottomPadding),
|
||||
state = scrollState,
|
||||
) {
|
||||
item {
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.view.MotionEvent
|
|||
import android.view.ViewConfiguration
|
||||
import androidx.compose.foundation.gestures.ScrollableState
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
|
@ -12,18 +13,24 @@ import androidx.compose.ui.composed
|
|||
import androidx.compose.ui.input.pointer.RequestDisallowInterceptTouchEvent
|
||||
import androidx.compose.ui.input.pointer.pointerInteropFilter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.InputDeviceCompat
|
||||
import androidx.core.view.MotionEventCompat
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun Modifier.scrollHandler(scrollState: ScrollableState): Modifier = composed {
|
||||
fun Modifier.rotaryEventHandler(scrollState: ScrollableState): Modifier = composed {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val scaledVerticalScrollFactor =
|
||||
remember { ViewConfiguration.get(context).getScaledVerticalScrollFactor() }
|
||||
remember { ViewConfiguration.get(context).scaledVerticalScrollFactor }
|
||||
val view = LocalView.current
|
||||
SideEffect {
|
||||
// Activate rotary scrolling
|
||||
view.requestFocus()
|
||||
}
|
||||
|
||||
this.pointerInteropFilter(RequestDisallowInterceptTouchEvent()) { event ->
|
||||
pointerInteropFilter(RequestDisallowInterceptTouchEvent()) { event ->
|
||||
if (event.action != MotionEvent.ACTION_SCROLL ||
|
||||
!event.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)
|
||||
) {
|
Loading…
Reference in a new issue