Android 我的改装应用程序在Kotlin的底部导航中使用时检索错误

Android 我的改装应用程序在Kotlin的底部导航中使用时检索错误,android,kotlin,retrofit,android-jetpack,android-jetpack-compose,Android,Kotlin,Retrofit,Android Jetpack,Android Jetpack Compose,我有一个经过改造的Android应用程序,它在片段中正常工作,检索我想要的数据列表,但是,一旦我决定在jetpack Compose上使用底部导航,同样的代码会给我一个错误 指定为非空的参数为空:方法kotlin.jvm.internal.Intrinsics.checkNotNullParameter,参数初始值 如果我在ComposeTree中将ScreenController的内容替换为composable(search)的内容,它可以工作,但不是这样 错误将nullParameter指向

我有一个经过改造的Android应用程序,它在片段中正常工作,检索我想要的数据列表,但是,一旦我决定在jetpack Compose上使用底部导航,同样的代码会给我一个错误

指定为非空的参数为空:方法kotlin.jvm.internal.Intrinsics.checkNotNullParameter,参数初始值

如果我在ComposeTree中将ScreenController的内容替换为composable(search)的内容,它可以工作,但不是这样

错误将nullParameter指向我的ImdbResponseMapper类

@AndroidEntryPoint
class MovieFragment : Fragment() {

    private val viewModel: MovieViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setContent {
                val movieList = viewModel.movie
                val movieSearch = viewModel.movieSearch.value
                val navController = rememberNavController()
                val title = remember {mutableStateOf("Search Movie")}

                Scaffold(
                    topBar = {
                        TopAppBar(
                           title = {
                               Text(text = title.value)
                           }
                        )
                    },
                    bottomBar = {
                        val items = listOf(
                            Screen.Search,
                            Screen.ToWatchList,
                            Screen.Watched
                        )
                        BottomNavigation {
                            val navBackStackEntry by navController.currentBackStackEntryAsState()
                            val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)

                            items.forEach {
                                BottomNavigationItem(
                                    icon = {Icon(it.icon, contentDescription = null)},
                                    selected = currentRoute == it.route,
                                    onClick = {
                                        navController.popBackStack(
                                            navController.graph.startDestination, false
                                        )
                                        if(currentRoute != it.route){
                                            navController.navigate(it.route)
                                        }
                                    })
                            }
                        }
                    }
                ) {
                    ScreenController(
                        navHostController = navController,
                        topBarTitle = title,
                        navController = findNavController(),
                        movieList = movieList,
                        viewModel = viewModel,
                        movieSearch = movieSearch
                    )
                }
            }
        }
    }
}
类ImdbRepositoryImpl(
私有val imdbService:imdbService,
私有值映射器:ImdbResponseMapper
):ImdbRepository{
覆盖挂起有趣的getMovie(查询:字符串):列表{
返回mapper.toDomainList(imdbService.getMovies(search=query.search)
}
}
@HiltViewModel
类MovieViewModel@injectconstructor(
私有val imdbRepository:imdbRepository
):ViewModel(){
val movie:MutableState=mutableStateOf(listOf())
趣味电影(搜索:字符串){
viewModelScope.launch{
movie.value=imdbRepository.getMovie(搜索)
}
}
val movieDetail:MutableState=mutableStateOf(null)
趣味getMovieDetails(imdbID:String){
viewModelScope.launch{
movieDetail.value=imdbRepository.getMovieDetails(imdbID)
}
}
val movieSearch=mutableStateOf(“”)
有趣的onTextChange(文本:字符串){
movieSearch.value=文本
}

这不是Jetpack的错。请仔细检查Model vs json中的非空字段。
@Composable
fun ScreenController(
    navHostController: NavHostController,
    topBarTitle: MutableState<String>,
    navController: NavController,
    movieList: MutableState<List<MovieSearch>>,
    viewModel: MovieViewModel,
    movieSearch: String
) {
    NavHost(
        navController = navHostController, startDestination = "search"
    ) {
        composable("search") {
            topBarTitle.value = "Search For Movies"
            Column(
                modifier = Modifier.padding(8.dp)
            ) {
                Row {
                    TextField(
                        value = viewModel.movieSearch.value,
                        onValueChange = { newValue ->
                            viewModel.onTextChange(newValue)
                        },
                        modifier = Modifier.weight(3f),
                        label = {
                            Text(text = "Search movies")
                        }
                    )
                    Button(
                        modifier = Modifier.weight(1f),
                        onClick = { viewModel.getMovie(movieSearch) }) {
                        Text(text = "Search")
                    }
                }
                if (movieList.value.isEmpty()) {
                    Column(
                        modifier = Modifier.fillMaxSize()
                    ) {
                        Text(
                            modifier = Modifier.align(Alignment.CenterHorizontally),
                            text = "Nothing to show"
                        )
                    }
                } else {
                    LazyColumn() {
                        items(items = movieList.value) { movie ->
                            SearchMovieLazyColumnItem(
                                movieSearch = movie,
                                onClick = {
                                    val action =
                                        MovieFragmentDirections.actionMovieFragmentToDetailFragment(
                                            movie.id, movie.title
                                        )
                                    navController.navigate(action)
                                }
                            )
                        }
                    }
                }
            }
        }
        composable("toWatchList"){
            topBarTitle.value = "Movies To Watch"
        }
        composable("watched"){
            topBarTitle.value = "Watched Movies"
        }
    }
}

sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
    object Search : Screen("search", "Search", Icons.Default.Search)
    object ToWatchList : Screen("toWatchList", "ToWatchList", Icons.Default.WatchLater)
    object Watched : Screen("watched", "Watched", Icons.Default.Archive)
}

class ImdbResponseMapper : DomainMapper<Response, MovieSearch> {

    override fun mapToDomainModel(model: Response): MovieSearch {
        return MovieSearch(
            id = model.imdbID,
            title = model.title,
            type = model.type,
            year = model.year,
            poster = model.poster
        )
    }

    fun toDomainList(initial: List<Response>): List<MovieSearch>{
        return initial.map { mapToDomainModel(it) }
    }
}
data class Response(
    val imdbID: String,
    @SerializedName("Poster")
    val poster: String,
    @SerializedName("Title")
    val title: String,
    @SerializedName("Type")
    val type: String,
    @SerializedName("Year")
    val year: String
)
data class MovieSearch (

    val id: String,
    val poster: String,
    val title: String,
    val type: String,
    val year: String
)
class ImdbRepositoryImpl(
    private val imdbService: ImdbService,
    private val mapper: ImdbResponseMapper
): ImdbRepository {
    override suspend fun getMovie(query: String): List<MovieSearch> {
        return mapper.toDomainList(imdbService.getMovies(search = query).search)
    }
}
@HiltViewModel
class MovieViewModel @Inject constructor(
    private val imdbRepository: ImdbRepository
) : ViewModel() {

    val movie: MutableState<List<MovieSearch>> = mutableStateOf(listOf())

    fun getMovie(search: String) {
        viewModelScope.launch {
            movie.value = imdbRepository.getMovie(search)
        }
    }

    val movieDetail: MutableState<MovieDetails?> = mutableStateOf(null)

    fun getMovieDetails(imdbID: String) {
        viewModelScope.launch {
            movieDetail.value = imdbRepository.getMovieDetails(imdbID)
        }
    }

    val movieSearch = mutableStateOf("")

    fun onTextChange(text: String) {
        movieSearch.value = text
    }