/
ImagesSearchGrid.kt
125 lines (115 loc) · 4.1 KB
/
ImagesSearchGrid.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package com.example.pixhub.ui.screens
import android.annotation.SuppressLint
import androidx.compose.animation.*
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.paint
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.pixhub.ui.data.ImageViewModel
import com.example.pixhub.utils.ApiType
import com.example.pixhub.utils.ImageTabItem
import com.google.accompanist.pager.*
import kotlinx.coroutines.launch
@SuppressLint("CoroutineCreationDuringComposition")
@OptIn(
ExperimentalFoundationApi::class, ExperimentalAnimationApi::class, ExperimentalPagerApi::class
)
@Composable
fun ImageSearchGrid(navController: NavHostController, imageViewModel: ImageViewModel) {
val coroutineScope = rememberCoroutineScope()
val pagerState = rememberPagerState()
val tabRowItems = listOf(
ImageTabItem(
apiType = ApiType.UNSPLASH,
screen = { Profile() }
),
ImageTabItem(
apiType = ApiType.PEXELS,
screen = { Settings() }
),
ImageTabItem(
apiType = ApiType.PIXABAY,
screen = { History() }
)
)
Column(modifier = Modifier.fillMaxSize()) {
TabRow(
backgroundColor = Color.Transparent.copy(0.1f),
modifier = Modifier
.padding(vertical = 4.dp, horizontal = 8.dp)
.clip(RoundedCornerShape(50)),
selectedTabIndex = pagerState.currentPage,
indicator = { tabPositions ->
CustomIndicator(tabPositions = tabPositions, pagerState = pagerState)
}
) {
tabRowItems.forEachIndexed { index, item ->
Tab(
modifier = Modifier
.clip(RoundedCornerShape(50))
.padding(horizontal = 16.dp)
.paint(
painter = painterResource(id = item.apiType.logo)
),
selected = pagerState.currentPage == index,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } }
)
}
}
HorizontalPager(
count = tabRowItems.size,
state = pagerState,
) {
tabRowItems[pagerState.currentPage].screen()
}
}
}
@OptIn(ExperimentalPagerApi::class)
@Composable
private fun CustomIndicator(tabPositions: List<TabPosition>, pagerState: PagerState) {
val transition = updateTransition(pagerState.currentPage, label = "")
val indicatorStart by transition.animateDp(
transitionSpec = {
if (initialState < targetState) {
spring(dampingRatio = 1f, stiffness = 50f)
} else {
spring(dampingRatio = 1f, stiffness = 100f)
}
}, label = ""
) {
tabPositions[it].left
}
val indicatorEnd by transition.animateDp(
transitionSpec = {
if (initialState < targetState) {
spring(dampingRatio = 1f, stiffness = 100f)
} else {
spring(dampingRatio = 1f, stiffness = 50f)
}
}, label = ""
) {
tabPositions[it].right
}
Box(
Modifier
.offset(x = indicatorStart)
.wrapContentSize(align = Alignment.BottomStart)
.width(indicatorEnd - indicatorStart)
.fillMaxSize()
.border(BorderStroke(2.dp, Color(0xFF00FFCC)), RoundedCornerShape(50))
.padding(5.dp)
)
}