I use a calendar from vanpra. I managed to hide the title. But I still have a huge headline. imageThat's what I have at the moment.
That's what I'd like to get. And can I somehow not use the new view with darkening around? I want to use date selection to view the schedule.image
Box(
modifier = Modifier
.fillMaxSize(0.5f)
) {
dateDialogState.show()
// настройки сценария/поведения (отклонение и т.д.)
MaterialDialog(
dialogState = dateDialogState,
backgroundColor = subviewsBackground,
) {
// сам выбор даты
datepicker(
// текущая дата
initialDate = LocalDate.now(),
colors = DatePickerDefaults.colors(
dateActiveBackgroundColor = Color.Red,
dateActiveTextColor = Color.White,
dateInactiveTextColor = Color.White,
calendarHeaderTextColor = Color.White,
headerBackgroundColor = subviewsBackground
),
waitForPositiveButton = false,
// разрешенная дата
allowedDateValidator = {
it.dayOfMonth % 2 == 1
}
) {
pickedDate = it
}
}
}
Related
I want to remove the blue oval color behind the selected item.
How can I do that?
NavigationBarItem(
selected = selected,
onClick = onClick,
icon = if (selected) selectedIcon else icon,
modifier = modifier,
enabled = enabled,
label = label,
alwaysShowLabel = alwaysShowLabel,
colors = NavigationBarItemDefaults.colors(
selectedIconColor = AppDefaults.navigationSelectedItemColor(),
unselectedIconColor = AppDefaults.navigationContentColor(),
selectedTextColor = AppDefaults.navigationSelectedItemColor(),
unselectedTextColor = AppDefaults.navigationContentColor(),
indicatorColor = AppDefaults.navigationIndicatorColor()
)
)
The color of the indicator is defined by the indicatorColor attribute in the NavigationBarItem.
To remove it you have to apply the same containerColor used by the NavigationBar.
If you are using the default (containerColor = surface color) you have to calculate the surface tonal color at different elevation applied to the containerColor.
Something like:
NavigationBarItem(
icon = { androidx.compose.material3.Icon(Icons.Filled.Favorite, contentDescription = item) },
label = { androidx.compose.material3.Text(item) },
selected = selectedItem == index,
onClick = { selectedItem = index },
colors = androidx.compose.material3.NavigationBarItemDefaults
.colors(
selectedIconColor = Red,
indicatorColor = MaterialTheme.colorScheme.surfaceColorAtElevation(LocalAbsoluteTonalElevation.current)
)
)
In the other cases just use the same color:
NavigationBar(
containerColor = Yellow
){
items.forEachIndexed { index, item ->
NavigationBarItem(
icon = { androidx.compose.material3.Icon(Icons.Filled.Favorite, contentDescription = item) },
label = { androidx.compose.material3.Text(item) },
selected = selectedItem == index,
onClick = { selectedItem = index },
colors = androidx.compose.material3.NavigationBarItemDefaults
.colors(
selectedIconColor = Red,
indicatorColor = Yellow )
)
}
}
I have 2 Radio Buttons to change the text color of a text (red text, hardcoded).
But i cant get the Text(color = Color.colorsTextRadio) to work.
I know it says it is a string but who do i get the Red or Green to convert to color.
If i have done something that could be better in thecode please tell because I'm a beginner.
#Composable
fun MainScreen() {
/**
* Text
*/
var text by remember {
mutableStateOf("test")
}
// Event handler
val onTextChange = { value: String ->
text = value
}
/**
* Colors
*/
val colors = listOf("Red", "Green")
var colorsTextRadio by remember {
mutableStateOf(colors[0])
}
// Event Handler
val onTextColorChange = { value: String ->
colorsTextRadio = value
}
Log.d("TAG", "MainScreen: colorsTextRadio $colorsTextRadio")
Column(modifier = Modifier.padding(6.dp)) {
TextField(value = text, onValueChange = onTextChange)
Text(text = text.replace("\n", " "), maxLines = 1, color = Color.Red)
RadioButtonGroup(colors = colors, colorsTextRadio = colorsTextRadio, onClick = onTextColorChange)
}
}
#Composable
fun RadioButtonGroup(
colors: List<String>,
colorsTextRadio: String,
onClick: (String) -> Unit
) {
Column(modifier = Modifier.selectableGroup()) {
colors.forEach { label ->
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.selectable(
selected = (colorsTextRadio == label),
onClick = { onClick.invoke(label) },
role = Role.RadioButton
)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
modifier = Modifier.padding(end = 16.dp),
selected = (colorsTextRadio == label),
onClick = null // null recommended for accessibility with screen readers
)
Text(text = label)
}
}
}
}
You can define a data class:
data class ColorLabel(
val label: String,
val color: Color
)
val colors = listOf(
ColorLabel("Red",Red),
ColorLabel("Green", Green))
var colorsTextRadio by remember { mutableStateOf(colors[0].label) }
var colorsText by remember { mutableStateOf(colors[0].color) }
Then apply them to your Composables:
Text(text = text.replace("\n", " "),
maxLines = 1,
color = colorsText)
Column(modifier = Modifier.selectableGroup()) {
colors.forEach { colorlabel->
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.selectable(
selected = (colorsTextRadio == colorlabel.label),
onClick = {
colorsTextRadio = colorlabel.label
colorsText = colorlabel.color
},
role = Role.RadioButton
)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
modifier = Modifier.padding(end = 16.dp),
selected = (colorsTextRadio == colorlabel.label),
onClick = null // null recommended for accessibility with screen readers
)
Text(text = colorlabel.label)
}
}
}
I want to create this type of slid switch using jetpack compose but I don't know how to do it can anyone help me with it? it will toggle between this 2 option
You can use TabRow like this:
val items = (0..1)
var activeTabIndex by remember { mutableStateOf(0) }
TabRow(
selectedTabIndex = activeTabIndex, backgroundColor = Color.Transparent,
indicator = {
Box(
Modifier
.tabIndicatorOffset(it[activeTabIndex])
.fillMaxSize()
.background(color = Color.Cyan)
.zIndex(-1F)
)
},
) {
items.mapIndexed { i, item ->
Tab(selected = activeTabIndex == i, onClick = { activeTabIndex = i }) {
Icon(
painter = painterResource(id = someIcon),
contentDescription = null,
tint = Color.Black,
modifier = Modifier.padding(vertical = 20.dp)
)
}
}
}
My problem is that i need a tab indicator to match exactly to the text that is above it (from designs):
However, all i managed to do is get something looking like this:
My code:
ScrollableTabRow(
selectedTabIndex = selectedSeason,
backgroundColor = Color.White,
edgePadding = 0.dp,
modifier = Modifier
.padding(vertical = 24.dp)
.height(40.dp),
indicator = { tabPositions ->
TabDefaults.Indicator(
color = Color.Red,
height = 4.dp,
modifier = Modifier
.tabIndicatorOffset(tabPositions[selectedSeason])
)
}
) {
item.seasonList().forEachIndexed { index, contentItem ->
Tab(
modifier = Modifier.padding(bottom = 10.dp),
selected = index == selectedSeason,
onClick = { selectedSeason = index }
)
{
Text(
"Season " + contentItem.seasonNumber(),
color = Color.Black,
style = styles.seasonBarTextStyle(index == selectedSeason)
)
}
}
}
}
Also a little bonus question, my code for this screen is inside lazy column, now i need to have this tab row to behave somewhat like a sticky header(when it gets to the top, screen stops scrolling, but i can still scroll the items inside it)
Thanks for your help
I had the same requirement, and came up with a simpler solution. By putting the same horizontal padding on the Tab and on the indicator, the indicator aligns with the tab's content:
ScrollableTabRow(selectedTabIndex = tabIndex,
indicator = { tabPositions ->
Box(
Modifier
.tabIndicatorOffset(tabPositions[tabIndex])
.height(TabRowDefaults.IndicatorHeight)
.padding(end = 20.dp)
.background(color = Color.White)
)
}) {
Tab(modifier = Modifier.padding(end = 20.dp, bottom = 8.dp),
selected = tabIndex == 0, onClick = { tabIndex = 0}) {
Text(text = "Tab 1!")
}
Tab(modifier = Modifier.padding(end = 20.dp, bottom = 8.dp),
selected = tabIndex == 1, onClick = { tabIndex = 1}) {
Text(text = "Tab 2!")
}
}
Have a look at the provided modifier, it internally computes a width value. If you change the Modifier yourself to the code below you can provide a width value.
fun Modifier.ownTabIndicatorOffset(
currentTabPosition: TabPosition,
currentTabWidth: Dp = currentTabPosition.width
): Modifier = composed(
inspectorInfo = debugInspectorInfo {
name = "tabIndicatorOffset"
value = currentTabPosition
}
) {
val indicatorOffset by animateAsState(
targetValue = currentTabPosition.left,
animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing)
)
fillMaxWidth()
.wrapContentSize(Alignment.BottomStart)
.offset(x = indicatorOffset + ((currentTabPosition.width - currentTabWidth) / 2))
.preferredWidth(currentTabWidth)
}
Now to the point of how to get the width of your Text:
Warning: I think it's not the way to do it but I can't figure out a better one atm.
At first, I create a Composable to provide me the width of its contents.
#Composable
fun MeasureWidthOf(setWidth: (Int) -> Unit, content: #Composable () -> Unit) {
Layout(
content = content
) { list: List<Measurable>, constraints: Constraints ->
check(list.size == 1)
val placeable = list.last().measure(constraints)
layout(
width = placeable.width.also(setWidth),
height = placeable.height
) {
placeable.placeRelative(x = 0, y = 0)
}
}
}
Now I can use it in your example (simplified):
// Needed for Android
fun Float.asPxtoDP(density: Float): Dp {
return (this / (density)).dp
}
fun main(args: Array<String>) {
Window(size = IntSize(600, 800)) {
val (selectedSeason, setSelectedSeason) = remember { mutableStateOf(0) }
val seasonsList = mutableListOf(2020, 2021, 2022)
val textWidth = remember { mutableStateListOf(0, 0, 0) }
// Android
val density = AmbientDensity.current.density
ScrollableTabRow(
selectedTabIndex = selectedSeason,
backgroundColor = Color.White,
edgePadding = 0.dp,
modifier = Modifier
.padding(vertical = 24.dp)
.height(40.dp),
indicator = { tabPositions ->
TabDefaults.Indicator(
color = Color.Red,
height = 4.dp,
modifier = Modifier
.ownTabIndicatorOffset(
currentTabPosition = tabPositions[selectedSeason],
// Android:
currentTabWidth = textWidth[selectedSeason].asPxtoDP(density)
// Desktop:
currentTabWidth = textWidth[selectedSeason].dp
)
)
}
) {
seasonsList.forEachIndexed { index, contentItem ->
Tab(
modifier = Modifier.padding(bottom = 10.dp),
selected = index == selectedSeason,
onClick = { setSelectedSeason(index) }
)
{
val text = #Composable {
Text(
text = "Season $contentItem",
color = Color.Black,
textAlign = TextAlign.Center
)
}
if (index == selectedSeason) {
MeasureWidthOf(setWidth = { textWidth[index] = it }) {
text()
}
} else {
text()
}
}
}
}
}
}
Edit (05.01.2021): Simplified Modifier code
Edit (09.01.2021): Fixed density problem on android and tested on Desktop and Android
Button(backgroundColor = Color.Yellow) {
Row {
Image(asset = image)
Spacer(4.dp)
Text("Button")
}
}
I can not figure out why I can't use background color on Button.
I followed the Compose Layout codelabs.
There is a problem in backgroundColor and asset in Image().
Use ButtonDefaults which is available in 1.0.0-alpha09 to alpha11
Button(
onClick = {},
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Yellow)
) {
/**/
}
OLD VERSION
The backgroundColor for Button no longer work in 1.0.0-alpha7
Use the below instead
Button(
onClick = {},
colors = ButtonConstants.defaultButtonColors(backgroundColor = Color.Yellow)
) {
/**/
}
You can use the ButtonDefaults.buttonColors
Button(
onClick = { },
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.White,
contentColor = Color.Red)
)
The ButtonConstants.defaultButtonColor is Deprecated at 1.0.0-alpha09 use :
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Yellow)
Update version 1.3.0 :
colors = ButtonDefaults.buttonColors(containerColor = Color.Yellow),
Compose background buttons color
create a variable mainButtonColor and define background Color and content Color
implementation 'androidx.compose.material3:material3:1.0.0-alpha02'
val mainButtonColor = ButtonDefaults.buttonColors(
containerColor = androidx.compose.ui.graphics.Color.Red,
contentColor = MaterialTheme.colorScheme.surface
)
Row {
Button(colors = mainButtonColor, onClick = {}, modifier = Modifier.padding(8.dp)) {
Text(text = "Custom colors")
}
}
Custom Colors
To create a custom color you need the RGB value of that color.
Button(
onClick = { },
colors = ButtonDefaults.buttonColors(
backgroundColor = Color(red = 255, green = 169, blue = 0)
)
) {}
backgroundColor = Color(red = 255, green = 169, blue = 0) is how we change the background color of the button to a custom color
STEP 1: Simple only set bg:
Button(
colors = buttonColors(Color.Red),
onClick = {}
) {
Text(text = "Login")
}
Full set colors:
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Red,
contentColor = Color.Green,
disabledBackgroundColor = Color.Yellow,
disabledContentColor = Color.Magenta
),
onClick = {}
) {
Text(text = "Login")
}
STEP 2 (optional): but this best practice
Material 2 case:
Color.Red change MaterialTheme.colors.primary
Material 3 case:
Color.Red change MaterialTheme.colorScheme.tertiaryContainer