Skip to content

Instantly share code, notes, and snippets.

@ulaserdegor
Last active December 7, 2022 11:11
Show Gist options
  • Save ulaserdegor/f435e115f343054108a22078bb9c4fdc to your computer and use it in GitHub Desktop.
Save ulaserdegor/f435e115f343054108a22078bb9c4fdc to your computer and use it in GitHub Desktop.
@file:OptIn(ExperimentalFoundationApi::class)
package com.ulaserdegor.sampleapp
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.Tab
import androidx.compose.material.TabRow
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
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.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlin.random.Random
@Composable
fun CustomScrollScreen() {
val scrollState = rememberLazyListState()
val activeTab = remember { mutableStateOf(CustomTab.TAB_1) }
LazyColumn(
state = scrollState,
modifier = Modifier
.background(Color(0xFFFAFAFA))
.fillMaxSize()
) {
item {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.setBackgroundGradient()
.fillMaxWidth()
.height(200.dp)
.padding(16.dp)
) {
Text(
text = "Area that can be filled with components such as images, text, etc.",
style = TextStyle(
color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold
),
textAlign = TextAlign.Center
)
}
}
stickyHeader {
CustomTabRow(
modifier = Modifier
.background(if (scrollState.firstVisibleItemIndex < 1) Color.Transparent else Color.White)
.padding(top = 12.dp, bottom = 8.dp),
activeTab = activeTab.value,
onTabClick = {
activeTab.value = it
}
)
if (scrollState.firstVisibleItemIndex > 0) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.background(
brush = Brush.verticalGradient(
colors = listOf(
Color.Black.copy(alpha = .1f),
Color.Transparent,
)
)
)
)
}
}
items(20) { index ->
Box(
contentAlignment = Alignment.CenterStart,
modifier = Modifier
.padding(horizontal = 8.dp)
.background(color = randomColor(), shape = RoundedCornerShape(8.dp))
.fillMaxWidth()
.height(64.dp)
.padding(16.dp)
) {
Text(text = "${activeTab.value.itemText}${(index + 1)}", color = Color.White)
}
Spacer(modifier = Modifier.height(8.dp))
}
}
}
@Composable
fun CustomTabRow(
modifier: Modifier = Modifier,
activeTab: CustomTab,
onTabClick: (CustomTab) -> Unit,
) {
TabRow(
selectedTabIndex = activeTab.ordinal,
backgroundColor = Color.Transparent,
indicator = {},
modifier = modifier
.height(44.dp)
.padding(horizontal = 8.dp),
divider = {
Divider(color = Color.Transparent)
}
) {
CustomTab.values().forEachIndexed { index, tab ->
Tab(
selected = activeTab == tab,
onClick = {
onTabClick.invoke(tab)
},
content = {
Box(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = if (index == 1) 8.dp else 0.dp)
.then(
if (activeTab == tab) {
Modifier
.clip(RoundedCornerShape(8.dp))
.setBackgroundGradient()
} else {
Modifier
.border(
BorderStroke(
width = 1.dp,
color = Color(0xFFF0F0F0)
),
shape = RoundedCornerShape(8.dp)
)
.background(
color = Color.White,
shape = RoundedCornerShape(8.dp)
)
}
)
.clickable {
onTabClick.invoke(tab)
},
contentAlignment = Alignment.Center
) {
Text(
text = tab.text,
color = if (activeTab == tab) Color.White
else Color.Black,
)
}
})
}
}
}
enum class CustomTab(
val text: String,
val itemText: String
) {
TAB_1(
text = "LIST 1",
itemText = "First tab item number: "
),
TAB_2(
text = "LIST 2",
itemText = "Second tab item number: "
),
TAB_3(
text = "LIST 3",
itemText = "Third tab item number: "
)
}
fun Modifier.setBackgroundGradient(): Modifier {
return this
.background(
brush = Brush.horizontalGradient(
listOf(
Color(0xFF3F51B5),
Color(0xFFFFEB3B)
)
)
)
}
/**
* Randomly turns dark colors.
*/
fun randomColor(): Color {
return Color(Random.nextInt(100), Random.nextInt(100), Random.nextInt(100))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment