首页 > 解决方案 > 如何在按钮单击上打开 datePicker?在喷气背包组成

问题描述

我已经使 datePicker 可组合,当我在单击 Icon 时调用该可组合时,它显示 @Composable 调用只能在可组合的上下文中发生

我只想在单击时打开日期选择器,然后按我的文本已更新。

我的日期选择器

@Composable
fun DatePicker(onDateSelected: (LocalDate) -> Unit, onDismissRequest: () -> Unit) {

val selDate = remember { mutableStateOf(LocalDate.now()) }

Dialog(onDismissRequest = { onDismissRequest() }, properties = DialogProperties()) {
    Column(
        modifier = Modifier
            .wrapContentSize()
            .background(
                color = MaterialTheme.colors.surface,
                shape = RoundedCornerShape(size = 16.dp)
            )
    ) {
        Column(
            Modifier
                .defaultMinSize(minHeight = 72.dp)
                .fillMaxWidth()
                .background(
                    color = MaterialTheme.colors.primary,
                    shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp)
                )
                .padding(16.dp)
        ) {
            Text(
                text = "Select date".uppercase(),
                style = MaterialTheme.typography.caption,
                color = MaterialTheme.colors.onPrimary
            )

            Spacer(modifier = Modifier.size(24.dp))

            Text(
                text = selDate.value.format(DateTimeFormatter.ofPattern("MMM d, YYYY")),
                style = MaterialTheme.typography.h4,
                color = MaterialTheme.colors.onPrimary
            )

            Spacer(modifier = Modifier.size(16.dp))
        }

        CustomCalendarView(onDateSelected = {
            selDate.value = it
        })

        Spacer(modifier = Modifier.size(8.dp))

        Row(
            modifier = Modifier
                .align(Alignment.End)
                .padding(bottom = 16.dp, end = 16.dp)
        ) {
            TextButton(
                onClick = onDismissRequest
            ) {
                //TODO - hardcode string
                Text(
                    text = "Cancel",
                    style = MaterialTheme.typography.button,
                    color = MaterialTheme.colors.onPrimary
                )
            }

            TextButton(
                onClick = {
                    onDateSelected(selDate.value)
                    onDismissRequest()
                }
            ) {
                //TODO - hardcode string
                Text(
                    text = "OK",
                    style = MaterialTheme.typography.button,
                    color = MaterialTheme.colors.onPrimary
                )
            }

        }
    }
}

}

@Composable
fun CustomCalendarView(onDateSelected: (LocalDate) -> Unit) {

AndroidView(
    modifier = Modifier.wrapContentSize(),
    factory = { context ->
        CalendarView(ContextThemeWrapper(context, R.style.CalenderViewCustom))
    },
    update = { view ->

        view.setOnDateChangeListener { _, year, month, dayOfMonth ->
            onDateSelected(
                LocalDate
                    .now()
                    .withMonth(month + 1)
                    .withYear(year)
                    .withDayOfMonth(dayOfMonth)
            )
        }
    }
)

}

视图模型类:

@HiltViewModel
class AddWeightViewModel @Inject() constructor(private val repository: WeightRepository) 
:
ViewModel() {

val weightState = mutableStateOf("")
val dateState = mutableStateOf("")

fun onWeightChange(weight: String) {
    weightState.value = weight
}

fun onDateChange(date : String) {
    dateState.value = date
}


fun addWeight() = viewModelScope.launch {

    val weight = Weight( 0,  weightState.value , dateState.value )
    repository.addWeight(weight)
}

}

我的体重屏幕:

@ExperimentalComposeUiApi
@Composable
fun AddWeightScreen(navController: NavController, viewModel: AddWeightViewModel) {

Column(modifier = Modifier
    .fillMaxSize()
    .background(color = MaterialTheme.colors.primary)
    .padding(bottom = 56.dp),

    verticalArrangement = Arrangement.SpaceBetween,
    horizontalAlignment = Alignment.CenterHorizontally
) {

    Text(text = "Cancel", fontSize = 16.sp, modifier = Modifier
        .padding(16.dp)
        .align(alignment = Alignment.Start)
        .clickable {
            navController.navigate(Screens.MyWeight.route)
        }, color = background)

    WeightData(viewModel)

    Button(
        onClick = {
            viewModel.addWeight()
            navController.navigate(Screens.MyWeight.route)
        },
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp),
        colors = ButtonDefaults.buttonColors(backgroundColor = background,
            contentColor = textDark)
    ) {

        Text(text = "Done", fontSize = 18.sp)

    }

}

}

@ExperimentalComposeUiApi
@Composable
fun WeightData(viewModel: AddWeightViewModel) {

val selDate = LocalDate.now()
val date = viewModel.dateState.value
val keyboardController = LocalSoftwareKeyboardController.current

Column(horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.spacedBy(22.dp),
    modifier = Modifier
        .drawBehind {
            drawCircle(
                color = textColor,
                radius = 450f,
                style = Stroke(width = 1.dp.toPx())
            )
        }

) {
    Text(text = "Enter Weight", color = Color.White.copy(alpha = .8f))

    TextField(
        value = viewModel.weightState.value,
        onValueChange = { viewModel.onWeightChange(it) },
        modifier = Modifier.background(color = MaterialTheme.colors.primary),
        keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Number,imeAction = ImeAction.Done),
        keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() }),
        singleLine = true)

    
    Row(verticalAlignment = Alignment.CenterVertically , horizontalArrangement = Arrangement.Center ) {

        Icon(imageVector = Icons.Default.DateRange,
            contentDescription = null,
            modifier = Modifier.clickable { DatePicker(onDateSelected = ) {
                
            }})
        
        Spacer(modifier = Modifier.width(20.dp))
        
        DatePicker(onDateSelected = {selDate}) {
            viewModel.onDateChange(date)
        }
        
    }

}

这就是我所做的。

标签: androidkotlinandroid-jetpack-compose

解决方案


推荐阅读