>  기사  >  룸 데이터베이스를 사용하여 제트팩의 모든 항목을 삭제한 후 UI가 다시 조립되지 않습니다.

룸 데이터베이스를 사용하여 제트팩의 모든 항목을 삭제한 후 UI가 다시 조립되지 않습니다.

WBOY
WBOY앞으로
2024-02-06 08:15:04481검색
질문 내용

jetpack compose를 사용하여 만든 영화 앱이 있습니다. 여기에는 사용자가 선택한 좋아하는 영화가 표시됩니다. 즐겨찾기는 UI에 완벽하게 존재해야 하는데, UI에서 항목을 삭제하면 변경 사항이 반영되도록 UI가 즉시 재구성되지 않습니다. 무엇을 해야 할까요?

이것이 내 UI입니다

으아아아

이것이 내 뷰 모델입니다

@composable
fun favscreen(
    movieviewmodel: movieviewmodel
) {

    remember { mutablestateof(movieviewmodel.getfavmovies()) }
    val shouldshowdialog = remember { mutablestateof(false) }
    val uistates = movieviewmodel.favs.collectasstate()


    column {
        row {
            text(
                text = "fav movies",
                fontsize = 25.sp,
                fontfamily = fontfamily(font(r.font.nsb)),
                modifier = modifier.padding(20.dp).weight(1f)
            )

            iconbutton(onclick = {
                shouldshowdialog.value  = true
            }) {
                icon(icons.filled.delete, contentdescription = "")
            }
        }
        when(val currentstate = uistates.value){
            is movieviewmodel.uistates.loading -> {
                box(modifier = modifier.fillmaxsize(), contentalignment = alignment.center) {
                    circularprogressindicator()
                }
            }
            is movieviewmodel.uistates.favs -> {
                val data = currentstate.data
                if(data.isempty()){
                    box(modifier = modifier.fillmaxsize(), contentalignment = alignment.center) {
                        text(
                            text = "no fav movies",
                            fontsize = 25.sp,
                            fontfamily = fontfamily(font(r.font.nsb)),
                            modifier = modifier.padding(20.dp))
                    }
                }
                else {
                    lazycolumn(){
                        items(data){ fav ->
                            row(modifier = modifier
                                .padding(20.dp)
                                .fillmaxwidth()
                                .clip(roundedcornershape(16.dp))
                                .background(color = color.darkgray)) {
                                asyncimage(
                                    model = utils.image_url + fav.imageurl,
                                    contentdescription = "",
                                    contentscale = contentscale.crop,
                                    filterquality = filterquality.high,
                                    modifier = modifier
                                        .width(150.dp)
                                        .height(150.dp))

                                column(modifier = modifier.padding(20.dp)) {
                                    text(
                                        text = fav.title!!,
                                        fontsize = 20.sp,
                                        fontfamily = fontfamily(font(r.font.nsb)))
                                    text(
                                        text = fav.rating.tostring() + "/10 imdb",
                                        fontsize = 15.sp,
                                        fontfamily = fontfamily(font(r.font.nsb)))
                                    text(
                                        text = "movie id : #" + fav.movieid,
                                        fontsize = 15.sp,
                                        fontfamily = fontfamily(font(r.font.nsb)))
                                }
                            }
                        }
                    }
                }
            }
            is movieviewmodel.uistates.error -> {
                box(modifier = modifier.fillmaxsize(), contentalignment = alignment.center){
                    text(
                        text = "no fav movies",
                        fontsize = 25.sp,
                        fontfamily = fontfamily(font(r.font.nsb)),
                        modifier = modifier.padding(20.dp))
                }
            }
            else -> {}
        }
    }
    if (shouldshowdialog.value){
        alertdialog(
            ondismissrequest = { shouldshowdialog.value = false },
            confirmbutton = {
                textbutton(onclick = {
                    movieviewmodel.deletemovies()
                    shouldshowdialog.value = false
                }) {
                    text(text = "proceed", fontfamily = fontfamily(font(r.font.nsm)))
                }
            },
            dismissbutton = {
                textbutton(onclick = {
                    shouldshowdialog.value = false
                }) {
                    text(text = "cancel", fontfamily = fontfamily(font(r.font.nsm)))
                }
            },
            shape = roundedcornershape(16.dp),
            text = { text(text = "favs deletion",fontfamily = fontfamily(font(r.font.nsb)))},
            title = { text(text = "do you want to delete all fav movies ?", fontfamily = fontfamily(font(r.font.nsb)))}
        )
    }
}

정답


_favs의 서면 사용법을 보면 문제가 매우 분명해집니다. getfavmovies만 업데이트됩니다.

"삭제 기능에서 UI 상태를 업데이트해야 합니다"처럼 들리겠지만, 저는 대체 솔루션을 제안하고 싶습니다. room + flows의 힘을 활용하세요!

먼저 스트림으로 저장될 뷰모델에서 loadingstate를 정의합니다.

으아아아

그런 다음 이 메커니즘을 사용하도록 getfavmovies() 함수를 변경하세요.

으아아아

마지막으로 상태와 데이터를 결합하여 마법을 일으키세요. 그 중 하나가 변경되면 자동으로 업데이트됩니다. :)

으아아아

면책조항: 철자 오류가 있을 수 있습니다. 아는 바가 없습니다

코드를 개선하여 이 답변을 마무리하겠습니다.

  1. 아무 것도 반환하지 않는 함수(= 用于不返回任何内容的函数(getfavmoviesinsertmoviedeletemovies)。否则,你会例如期望 getfavmovies, insertmovie, deletemovies)에 =를 사용하지 마세요. 그렇지 않으면 예를 들어

    영화 목록을 반환할 것이라고 예상할 것입니다
  2. remember { mutablestateof(movieviewmodel.getfavmovies()) } 并没有真正的 remember 任何东西,是吗?这太令人恼火了。我建议将其移至 viewmodel 中: init { movieviewmodel.getfavmovies() }

  3. val uistates = movieviewmodel.favs.collectasstate():命名意味着这是多个 ui 状态,请使用单数; uistates 类本身也是如此。另外,如果这里直接使用“.value”,可以跳过这里的重新声明:when(val currentstate = uistates.value)

  4. mutablelist9fed9bb6bc0c66d7a13f33ab448de4c5。对 ui 状态使用可变值是一个坏主意,例如它可能会混淆您的 stateflow귀하의 주에는 이 포함되어 있습니다. 이런 상황을 피하십시오. 그냥 기존 목록을 사용하세요 :) https://www.php.cn/link/ff685590317f1330efc73f396ac92cd7

  5. collectasstatewithlifecycle() 而不是 collectasstate()를 사용하세요. https://medium.com/androiddevelopers/consuming-flows를 참조하세요 - jetpack-compose-cde014d0d5a3에서 안전하게

  6. repoimpl뷰 모델에서

    에 액세스해서는 안 됩니다. 저장소를 인터페이스와 구현으로 분할한다는 전체 아이디어는 구현을 숨기는 것입니다
  7. 화면 구성 가능 항목을 정의하는 것이 좋습니다. 뷰 모델은 필요하지 않고 데이터만 필요합니다. https://developer.android.com/jetpack/compose/state#state-hoisting

    과 유사합니다.

.🎜 으아아아

위 내용은 룸 데이터베이스를 사용하여 제트팩의 모든 항목을 삭제한 후 UI가 다시 조립되지 않습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제