通过CalendarView点击不同日期选择日期时如何检索条目

问题描述 投票:0回答:1

我试图通过单击屏幕上的 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”,然后加载所有条目,以便它可以与条目卡一起使用显示条目的功能。

谢谢!

android-jetpack-compose android-room android-viewmodel dagger-hilt calendarview
1个回答
0
投票
  1. EntryViewModel
    loadEntryList()
    函数中出现错误:在ViewModel的
    date
    函数中调用
    getEntryFromDate()
    时缺少
    loadEntryList()
    参数。您需要将
    date
    参数传递给存储库函数。

  2. CalendarScreen
    中,需要将选定的
    queryDateInLong
    传递给ViewModel中的
    loadEntryList()
    函数。

解决方法如下:

EntryViewModel

fun loadEntryList(date: Long) {
    viewModelScope.launch {
        _entries.value = repository.getEntryFromDate(date)
    }
}

CalendarScreen

coroutineScope.launch {
    viewModel.loadEntryList(queryDateInLong)
}

通过这些更改,当您单击 CalendarView 中的日期时,它将在数据库中查询与该日期对应的条目,并相应地更新 UI。

© www.soinside.com 2019 - 2024. All rights reserved.