数据没有JetPack撰写COM Date Picker
#kotlin #android #jetpackcompose

使用日期是各种应用程序中非常普遍的任务,无论是用于注册,调度,结论指示等...在JetPack撰写标准库中,我们无法访问组件来处理日期!

换句话说,或者我们需要手动实现composeble,否则我们可以使用Android SDK选择器...幸运的是,从1.2.0 dos componentes do Material Design 3 para Jetpack Compose版本中,我们可以访问新的选择,例如Abiaoqian!P>

在本文中,我将向您展示如何在JetPack Compiss中使用它。

检查依赖性

首先,检查koud0依赖的版本非常重要。通常,未指定版本,即取决于其实施的那一刻,它可以在1.2.0之前使用版本!

之前使用版本。

在这种情况下,它是build.gradle.kts,并手动添加版本:

dependencies {
    // dependências
    implementation("androidx.compose.material3:material3:1.2.0-alpha02")
}

如果有警告表明有更多最新版本,则可能不需要指定版本,例如1.2.0或最近的版本。

随着附加的依赖,我们可以实现合并。


tl; dr

对于只想要示例案例的人,它遵循合成的结尾:

val focusManager = LocalFocusManager.current
var showDatePickerDialog by remember {
    mutableStateOf(false)
}
val datePickerState = rememberDatePickerState()
var selectedDate by remember {
    mutableStateOf("")
}
if (showDatePickerDialog) {
    DatePickerDialog(
        onDismissRequest = { showDatePickerDialog = false },
        confirmButton = {
            Button(
                onClick = {
                    datePickerState
                        .selectedDateMillis?.let { millis ->
                            selectedDate = millis.toBrazilianDateFormat()
                        }
                    showDatePickerDialog = false
                }) {
                Text(text = "Escolher data")
            }
        }) {
        DatePicker(state = datePickerState)
    }
}
TextField(
    value = selectedDate,
    onValueChange = { },
    Modifier
        .padding(8.dp)
        .fillMaxWidth()
        .onFocusEvent {
            if (it.isFocused) {
                showDatePickerDialog = true
                focusManager.clearFocus(force = true)
            }
        },
    label = {
        Text("Date")
    },
    readOnly = true
)

您可以按照自己的要求实现的日期组合器,但是您也可以使用我创建的此扩展名:

fun Long.toBrazilianDateFormat(
    pattern: String = "dd/MM/yyyy"
): String {
    val date = Date(this)
    val formatter = SimpleDateFormat(
        pattern, Locale("pt-br")
    ).apply {
        timeZone = TimeZone.getTimeZone("GMT")
    }
    return formatter.format(date)
}

这种方式必须呈现以下结果:

App em execução, apresenta caixa de diálogo com o date picker ao clicar no campo de texto 'Date'. Ao clicar no botão 'Escolher data', fecha a caixa de diálogo e mostra a data formatada no padrão dd/MM/yyyy no campo de texto. Ao abrir novamente a caixa de diálogo e clicar fora do escopo, apenas fecha a caixa de diálogo.

要理解这种方式的动机,请遵循其余的遏制。 ð


在屏幕上使用datepicker

选择器的用法相对简单:

val datePickerState = rememberDatePickerState()
DatePicker(state = datePickerState)

App em execução apresentando o DatePicker na tela inteira

请参阅只需致电可兼容的DatePicker,我们就有一个专用屏幕来选择日期。部分,这个县不足以获得所选的日期!

为此,DatePicker提供了Koud4的Koud4属性,但是只有获得价值的访问将无法提供完整的使用体验!

将文本字段添加到日期

当我们想从采摘者提供日期时,我们通常会使用另一个组件打开选择器并显示所选日期(例如表单),我们将为此类提供一个文本字段:

var selectedDate by remember() {
    mutableStateOf("")
}
TextField(
    value = selectedDate,
    onValueChange = { },
    Modifier
        .padding(8.dp)
        .fillMaxWidth(),
    label = {
        Text("Date")
    },
    readOnly = true
)

App em execução apresentando um campo de texto com a label 'Date'

入口,我们需要将koud6与koud2集成。尽管可以将DatePicker用于此解决方案,但是只有与拾音器一起实现往往更为复杂,因为有羊毛可以显示或隐藏它...

使用diatologue盒进行日期选择器

为了促进DatePicker的实现,让我们去koud10。基本上,我们具有caixa de diálogo do Android的标准行为。一个常见的情况之一是不想选择一个日期,而对话框只需单击上下文:

var selectedDate by remember {
    mutableStateOf("")
}
val datePickerState = rememberDatePickerState()
DatePickerDialog(
    onDismissRequest = { /*TODO*/ },
    confirmButton = { /*TODO*/ }) {
    DatePicker(state = datePickerState)
}
TextField(
    value = selectedDate,
    onValueChange = { },
    Modifier
        .padding(8.dp)
        .fillMaxWidth(),
    label = {
        Text("Date")
    },
    readOnly = true
)

App em execução exibindo a caixa de dialogo apresentado o date picker

现在,我们需要集成羊毛才能在单击TextField时显示采摘日期。

从textfield显示datepickerdialog

鉴于我们使用Koud12,它对点击没有反应!因此,我们需要对其他事件做出反应,例如重点关注:

var showDatePickerDialog by remember {
    mutableStateOf(false)
}
var selectedDate by remember {
    mutableStateOf("")
}
val datePickerState = rememberDatePickerState()
if (showDatePickerDialog) {
    DatePickerDialog(
        onDismissRequest = { /*TODO*/ },
        confirmButton = { /*TODO*/ }) {
        DatePicker(state = datePickerState)
    }
}
TextField(
    value = selectedDate,
    onValueChange = { },
    Modifier
        .padding(8.dp)
        .fillMaxWidth()
        .onFocusChanged {
            if (it.isFocused) {
                showDatePickerDialog = true
            }
        },
    label = {
        Text("Date")
    },
    readOnly = true
)

App em execução, ao clicar no campo de texto para data, abre a caixa de diálogo e exibe o Data Picker. Ao clicar fora do diálogo ele não é fechado

请注意,杜松子盒显示日期选择器,POR,它不会通过单击上下文来关闭,这是我们在这种类型的组件中期望的行为。

实施羊毛以关闭对话框

要实现此解决方案,我们需要配置Koud13或Koud14 Parano并添加此行为:

if (showDatePickerDialog) {
    DatePickerDialog(
        onDismissRequest = { showDatePickerDialog = false },
        confirmButton = {
            Button(onClick = { showDatePickerDialog = false }) {
                Text(text = "Escolher data")
            }
        }) {
        DatePicker(state = datePickerState)
    }
}

App em execução, abrindo caixa de diálogo com Date Picker e botão de escolher data ao clicar no campo de texto 'Date'. Ao clicar fora do escopo do dialog, ele é fechado novamente. Ao tentar abrir novamente a caixa de diálogo, ela não é aberta

请注意,关闭对话框的行为有效,但是不可能再次打开它!发生这种情况是因为在JetPack Compiss中,专注于文本字段时,如果我们与ADECARINAD ADING ADING ADINE CONDES ADERES COMET COMET INSTERINC进行互动时,焦点事件正在发生变化。

操纵元素的焦点

鉴于我们没有另一个要素可以集中在屏幕上,而且还取决于另一个要显示日期选择器的元素,这是一种pine体验,我们将手动修改焦点!

为此,我们使用焦点管理器并清理对所需事件的重点,在这种情况下,将重点放在Koud6上:

val focusManager = LocalFocusManager.current
...
TextField(
    value = selectedDate,
    onValueChange = { },
    Modifier
        .padding(8.dp)
        .fillMaxWidth()
        .onFocusEvent {
            if (it.isFocused) {
                showDatePickerDialog = true
                focusManager.clearFocus(force = true)
            }
        },
    label = {
        Text("Date")
    },
    readOnly = true
)

App em execução, ao clicar no campo de texto 'Date', a caixa diálogo com o Date Picker é apresentada. Ao clicar fora do escopo da caixa de diálogo, a caixa de diálogo é fechada e apresenta o campo de texto 'Date' sem foco, ao clicar novamente no campo de texto, abre a caixa de diálogo. Ao clicar no botão 'Escolher data' a caixa de diálogo é fechada também

请参阅现在的对话框在预期的情况下开放和关闭!缺少的是获取所选日期的价值并将其显示在文本字段中。

显示在Textfield中选择的日期

为此,我们需要对必须填写文本字段的正确事件做出反应。在当前上下文中,我们有“选择数据” botan,它将负责操纵填充koud6的koud16状态。

长(毫秒)字符串的格式化日期

考虑到应用程序中通常不会通过毫秒呈现日期的显示,让我们在Koud19中添加一个Koud18构成器,使其为我们提供,我们甚至可以考虑一个扩展名:

fun Long.toBrazilianDateFormat(
    pattern: String = "dd/MM/yyyy"
): String {
    val date = Date(this)
    val formatter = SimpleDateFormat(
        pattern, Locale("pt-br")
    ).apply {
        timeZone = TimeZone.getTimeZone("GMT")
    }
    return formatter.format(date)
}

并且在准备好对话功能后,我们只需要调整Botan的点击事件:

DatePickerDialog(
    onDismissRequest = { showDatePickerDialog = false },
    confirmButton = {
        Button(
            onClick = {
                datePickerState
                    .selectedDateMillis?.let { millis ->
                        selectedDate = millis.toBrazilianDateFormat()
                    }
                    showDatePickerDialog = false
            }) {
            Text(text = "Escolher data")
        }
    }) {
    DatePicker(state = datePickerState)
}
...

App em execução, apresenta caixa de diálogo com o date picker ao clicar no campo de texto 'Date'. Ao clicar no botão 'Escolher data', fecha a caixa de diálogo e mostra a data formatada no padrão dd/MM/yyyy no campo de texto. Ao abrir novamente a caixa de diálogo e clicar fora do escopo, apenas fecha a caixa de diálogo.

请参阅现在我们的选择器日期正常工作!

您如何看待Jetpack Compiss中的日期选择器的实现?你喜欢遏制吗?借此机会留下类似的机会并与伙计们分享ð