Skip to content

Commit 3cc9ca3

Browse files
committed
ui: improve library screen
1 parent 2862510 commit 3cc9ca3

1 file changed

Lines changed: 84 additions & 11 deletions

File tree

  • features/library/ui/src/main/java/org/mrlem/composesample/features/library/ui/list

features/library/ui/src/main/java/org/mrlem/composesample/features/library/ui/list/ListScreen.kt

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
11
package org.mrlem.composesample.features.library.ui.list
22

3+
import androidx.compose.animation.AnimatedVisibility
4+
import androidx.compose.animation.fadeIn
5+
import androidx.compose.animation.fadeOut
6+
import androidx.compose.foundation.background
37
import androidx.compose.foundation.layout.Box
48
import androidx.compose.foundation.layout.Column
59
import androidx.compose.foundation.layout.fillMaxSize
610
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.height
712
import androidx.compose.foundation.layout.padding
813
import androidx.compose.foundation.lazy.LazyColumn
914
import androidx.compose.foundation.lazy.items
15+
import androidx.compose.foundation.lazy.rememberLazyListState
1016
import androidx.compose.foundation.shape.CircleShape
1117
import androidx.compose.material.icons.Icons
1218
import androidx.compose.material.icons.filled.Add
1319
import androidx.compose.material3.FloatingActionButton
1420
import androidx.compose.material3.Icon
21+
import androidx.compose.material3.MaterialTheme
1522
import androidx.compose.material3.SnackbarHostState
1623
import androidx.compose.material3.Surface
24+
import androidx.compose.material3.Text
1725
import androidx.compose.material3.TextField
26+
import androidx.compose.material3.TextFieldDefaults
1827
import androidx.compose.runtime.Composable
1928
import androidx.compose.runtime.LaunchedEffect
2029
import androidx.compose.runtime.collectAsState
30+
import androidx.compose.runtime.derivedStateOf
2131
import androidx.compose.runtime.getValue
2232
import androidx.compose.runtime.mutableStateOf
2333
import androidx.compose.runtime.remember
2434
import androidx.compose.runtime.setValue
2535
import androidx.compose.ui.Alignment
2636
import androidx.compose.ui.Modifier
37+
import androidx.compose.ui.graphics.Brush
38+
import androidx.compose.ui.graphics.Color
2739
import androidx.compose.ui.text.input.TextFieldValue
2840
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
2941
import org.mrlem.android.core.feature.ui.UiModePreviews
@@ -43,6 +55,7 @@ internal fun ListScreen(
4355
when (effect) {
4456
is ListViewEffect.GoToItem ->
4557
onItemSelect(effect.id)
58+
4659
is ListViewEffect.ShowError ->
4760
snackbarHostState.showSnackbar("Failed to retrieve data")
4861
}
@@ -53,25 +66,51 @@ internal fun ListScreen(
5366
viewModel.handleRedirections()
5467
}
5568

69+
ListScreen(
70+
state = state,
71+
onAction = viewModel::onAction,
72+
)
73+
}
74+
75+
@Composable
76+
private fun ListScreen(
77+
state: ListViewState,
78+
onAction: (ListViewAction) -> Unit,
79+
) {
5680
Column {
5781
var fieldValue by remember {
5882
mutableStateOf(TextFieldValue(state.filter))
5983
}
84+
6085
TextField(
6186
value = fieldValue,
87+
singleLine = true,
6288
onValueChange = {
6389
fieldValue = it
64-
viewModel.onAction(ListViewAction.FilterChange(it.text))
90+
onAction(ListViewAction.FilterChange(it.text))
6591
},
92+
shape = MaterialTheme.shapes.medium,
93+
colors = TextFieldDefaults.colors(
94+
focusedIndicatorColor = Color.Transparent,
95+
unfocusedIndicatorColor = Color.Transparent,
96+
disabledIndicatorColor = Color.Transparent,
97+
errorIndicatorColor = Color.Transparent,
98+
),
99+
placeholder = { Text("Filter articles") },
66100
modifier = Modifier
67-
.fillMaxWidth(),
101+
.fillMaxWidth()
102+
.padding(
103+
start = Theme.size.medium,
104+
top = Theme.size.medium,
105+
end = Theme.size.medium,
106+
),
68107
)
69108

70109
List(
71110
state = state,
72111
modifier = Modifier
73112
.fillMaxSize(),
74-
onAction = viewModel::onAction,
113+
onAction = onAction,
75114
)
76115
}
77116
}
@@ -85,14 +124,47 @@ private fun List(
85124
Box(
86125
modifier = modifier,
87126
) {
88-
LazyColumn(
127+
val listState = rememberLazyListState()
128+
129+
val showShadow by remember {
130+
derivedStateOf { listState.canScrollBackward }
131+
}
132+
133+
Box(
89134
modifier = Modifier
90-
.fillMaxSize(),
135+
.fillMaxWidth(),
91136
) {
92-
items(state.items) {
93-
ListItem(
94-
viewState = it,
95-
onAction = onAction,
137+
LazyColumn(
138+
state = listState,
139+
modifier = Modifier
140+
.fillMaxSize(),
141+
) {
142+
items(state.items) {
143+
ListItem(
144+
viewState = it,
145+
onAction = onAction,
146+
)
147+
}
148+
}
149+
150+
AnimatedVisibility(
151+
visible = showShadow,
152+
enter = fadeIn(),
153+
exit = fadeOut(),
154+
modifier = Modifier.align(Alignment.TopCenter),
155+
) {
156+
Box(
157+
modifier = Modifier
158+
.fillMaxWidth()
159+
.height(Theme.size.medium)
160+
.background(
161+
brush = Brush.verticalGradient(
162+
colors = listOf(
163+
MaterialTheme.colorScheme.background,
164+
Color.Transparent,
165+
),
166+
),
167+
),
96168
)
97169
}
98170
}
@@ -102,7 +174,7 @@ private fun List(
102174
shape = CircleShape,
103175
modifier = Modifier
104176
.padding(Theme.size.medium)
105-
.align(Alignment.TopEnd),
177+
.align(Alignment.BottomEnd),
106178
) {
107179
Icon(imageVector = Icons.Filled.Add, contentDescription = "Import random bookmark")
108180
}
@@ -114,7 +186,7 @@ private fun List(
114186
private fun Preview() {
115187
Theme {
116188
Surface {
117-
List(
189+
ListScreen(
118190
state = ListViewState(
119191
items = listOf(
120192
ListItemViewState(
@@ -128,6 +200,7 @@ private fun Preview() {
128200
),
129201
),
130202
),
203+
onAction = {},
131204
)
132205
}
133206
}

0 commit comments

Comments
 (0)