我试图通过单击屏幕上的 CalendarView 来查询条目(1 个或多个),但我陷入了尝试弄清楚如何继续以显示这些条目(因为我是新的)的过程中。我不理解视图模型,所以对我来说很难弄清楚这部分,因为要求我传递参数也有一个错误。
屏幕(我正在尝试将日期转换为 Long,没有时间查询数据库并加载具有特定日期的条目,但我无法真正找到将条目加载到变量中以传递到条目卡中所需的内容功能):
fun CalendarScreen(
navController: NavController,
viewModel: EntryViewModel = hiltViewModel()
) {
var queryDate = Calendar.getInstance()
val coroutineScope = rememberCoroutineScope()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
AndroidView(factory = { CalendarView(it) }, update = {
it.setOnDateChangeListener { calendarView, year, month, day ->
//query only the date
queryDate = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
set(Calendar.YEAR, year)
set(Calendar.MONTH, month)
set(Calendar.DAY_OF_MONTH, day)
}
val queryDateInLong = queryDate.timeInMillis //Convert date to long
coroutineScope.launch {
viewModel.loadEntryList(queryDateInLong)
}
}
}
)
Spacer(modifier = Modifier.height(10.dp))
LazyColumn(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.background(Color.White)) {
stickyHeader {
Text("Entries", fontFamily = FontFamily.Serif, fontSize = 22.sp)
EntryCard()
}
}
}
}
@Composable
fun EntryCard(entry: Entry) {
var cardColor = ""
//Compare emotion input from entry to map to retrieve # color string
if (emotionToColor.containsKey(entry.emotionEntry)) {
cardColor = emotionToColor[entry.emotionEntry].toString()
}
val cardColorBackground = cardColor.toColor() //Convert to color for card
var expanded by remember { mutableStateOf(false) }
val dateConvert = Calendar.getInstance().apply { timeInMillis = entry.dateEntryInMillis }
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.background(cardColorBackground)
.height(35.dp)
.fillMaxWidth()
.clickable { expanded = !expanded }
) {
AnimatedContent(
targetState = expanded,
transitionSpec = {
fadeIn(animationSpec = tween(150,150)) togetherWith
fadeOut(animationSpec = tween(150)) using
SizeTransform { initialSize, targetSize ->
if (targetState) {
keyframes {
IntSize(targetSize.width, initialSize.height) at 150
durationMillis = 300
}
} else {
keyframes { IntSize(initialSize.width, targetSize.height) at 150
durationMillis = 300
}
}
}
}, label = ""
) { targetExpanded ->
if (targetExpanded) {
Text(text = entry.journalEntry,
fontSize = 18.sp,
textAlign = TextAlign.Justify)
} else {
Text(text = "${entry.emotionEntry}: $dateConvert ${entry.timeEntry}", fontSize = 24.sp, textAlign = TextAlign.Center)
}
}
}
Spacer(modifier = Modifier.height(10.dp))
}
数据仓库:
class DataRepository @Inject constructor(private val entryDAO: EntryDAO, private val date: Long) {
suspend fun saveEntry(entry: Entry) {
return entryDAO.saveEntry(entry)
}
suspend fun deleteEntry(entry: Entry) {
return entryDAO.deleteEntry(entry)
}
suspend fun getEntryFromDate(): List<Entry> {
return entryDAO.getEntryFromDate(date)
}
}
入门班
@Entity(tableName = "entry_table")
data class Entry(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "Emotion") val emotionEntry: String,
@ColumnInfo(name = "Journal") val journalEntry: String,
@ColumnInfo(name = "Date") val dateEntryInMillis: Long,
@ColumnInfo(name = "Time") val timeEntry: String
) {
}
DAO 类
@Dao
interface EntryDAO {
@Upsert
suspend fun saveEntry(entry: Entry)
@Delete
suspend fun deleteEntry(entry: Entry)
@Query("SELECT * FROM entry_table WHERE Date = :dateInLong") //retrieve emotion, journal, time and date from a date
suspend fun getEntryFromDate(dateInLong: Long): List<Entry>
}
ViewModel(我正在遵循 github 的指南来使柄室数据库正常工作,但我不太了解如何制作视图模型):
init { loadEntryList() } 也有一个错误,因为没有日期参数,但我不确定要放入什么。
错误: “没有为参数‘日期’传递任何值”
@HiltViewModel
class EntryViewModel @Inject constructor(private val repository: DataRepository) : ViewModel() {
private val _entries = mutableStateOf<List<Entry>>(emptyList())
val entries: State<List<Entry>> = _entries
init {
loadEntryList()
}
fun loadEntryList(date: Long) {
viewModelScope.launch {
_entries.value = repository.getEntryFromDate()
}
}
suspend fun saveEntry(entry: Entry) {
viewModelScope.launch {
repository.saveEntry(entry)
}
}
}
我希望当我点击 CalendarView 上的任何日期时,应用程序会将日期转换为 Long 并从条目类中查询“DateInMillis”,然后加载所有条目,以便它可以与条目卡一起使用显示条目的功能。
谢谢!
EntryViewModel
的loadEntryList()
函数中出现错误:在ViewModel的date
函数中调用getEntryFromDate()
时缺少loadEntryList()
参数。您需要将 date
参数传递给存储库函数。
在
CalendarScreen
中,需要将选定的queryDateInLong
传递给ViewModel中的loadEntryList()
函数。
解决方法如下:
在
EntryViewModel
:
fun loadEntryList(date: Long) {
viewModelScope.launch {
_entries.value = repository.getEntryFromDate(date)
}
}
在
CalendarScreen
:
coroutineScope.launch {
viewModel.loadEntryList(queryDateInLong)
}
通过这些更改,当您单击 CalendarView 中的日期时,它将在数据库中查询与该日期对应的条目,并相应地更新 UI。