如何修复 Android Studio 中的“java.lang.IndexOutOfBoundsException: Index: 2, Size: 2”问题

How to fix "java.lang.IndexOutOfBoundsException: Index: 2, Size: 2" problem in Android Studio

提问人:Zainal Abidin 提问时间:11/12/2023 最后编辑:SörenZainal Abidin 更新时间:11/12/2023 访问量:38

问:

我正在尝试通过利用 ViewModel 构建搜索功能来根据搜索输入框中的查询搜索数据。但是,当我尝试输入查询时,第一次可以显示数据时,我收到错误“java.lang.IndexOutOfBoundsException: Index: 2, Size: 2”。请帮我解决这个问题。

以下是我项目的完整代码:

搜索屏幕.kt :

@Composable
fun SearchScreen(
    navController: NavController,
    daftarWisataViewModel: DaftarWisataViewModel = viewModel(
        factory = ViewModelDaftarWisataFactory(
            Injection.provideDaftarWisataRepository()
        )
    )
) {
    val daftarResult by daftarWisataViewModel.uiState.collectAsState()
    val searchText = remember { mutableStateOf("") }
    val listState = rememberLazyListState()
    val isAscending = remember { mutableStateOf(true) }
    val isFirstSorting = remember { mutableStateOf(true) }

    LaunchedEffect(daftarWisataViewModel) {
        if (daftarResult is UiState.Loading) {
            daftarWisataViewModel.getPopular()
        }
    }

    Scaffold(
        topBar = { SearchWisata(searchText, isAscending, isFirstSorting, daftarWisataViewModel) }
    ) { paddingValues ->
        when (daftarResult) {
            is UiState.Loading -> {
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(color = ColorWhite2),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {}
            }
            is UiState.Success -> {
                val dataResult = (daftarResult as UiState.Success<DaftarWisataResponse>).data
                val dataWisata: List<DataDaftarResponse> = dataResult.data
                LazyColumn(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(color = ColorWhite2)
                        .padding(top = paddingValues.calculateTopPadding()),
                    state = listState
                ) {
                    val sortedData = if (isFirstSorting.value) {
                        dataWisata
                    } else {
                        if (isAscending.value) {
                            dataWisata.sortedBy { it.name }
                        } else {
                            dataWisata.sortedByDescending { it.name }
                        }
                    }
                    items(sortedData) { item ->
                        CardWisataTerdekat(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(start = 18.dp, end = 18.dp, top = 10.dp),
                            item = item,
                            navController = navController
                        )
                    }
                }
            }
            is UiState.Error -> {}
        }
    }
}

@Composable
fun SearchWisata(
    searchText: MutableState<String>,
    isAscending: MutableState<Boolean>,
    isFirstSorting: MutableState<Boolean>,
    daftarWisataViewModel: DaftarWisataViewModel,
) {
    val query by daftarWisataViewModel.query
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(0.8f)
        ) {
            SearchField(
                placeholder = "Cari tempat wisata",
                value = query,
                onValueChange = daftarWisataViewModel::searchWisata,
                onClear = { searchText.value = "" },
            )
        }
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(start = 8.dp)
                .weight(0.1f), horizontalAlignment = Alignment.End
        ) {
            IconButton(
                onClick = {
                    if (isFirstSorting.value) {
                        isFirstSorting.value = false
                    }
                    isAscending.value = !isAscending.value
                },
            ) {
                Icon(
                    modifier = Modifier.width(26.dp),
                    painter = painterResource(id = if (isAscending.value) R.drawable.ic_ascending else R.drawable.ic_descending),
                    contentDescription = if (isAscending.value) "Urutkan Ascending" else "Urutkan Descending",
                    tint = ColorGray
                )
            }
        }
    }
}

DaftarWisataViewModel.kt :

class DaftarWisataViewModel(private val repository: DaftarWisataRepository) : ViewModel() {
    private val _uiState: MutableStateFlow<UiState<DaftarWisataResponse>> =
        MutableStateFlow(UiState.Loading)
    val uiState: StateFlow<UiState<DaftarWisataResponse>> get() = _uiState

    private var wisataData: DaftarWisataResponse? = null

    private val _query = mutableStateOf("")
    val query: State<String> get() = _query

    fun getPopular() {
        viewModelScope.launch {
            try {
                _uiState.value = UiState.Loading
                val response = repository.getPopular()
                wisataData = response
                _uiState.value = UiState.Success(response)
            } catch (e: Exception) {
                _uiState.value = UiState.Error(R.string.something_wrong.toString())
            }
        }
    }

    fun searchWisata(query: String) {
        _query.value = query
        viewModelScope.launch {
            try {
                val filteredData = repository.searchWisata(query, wisataData!!)
                _uiState.value = UiState.Success(DaftarWisataResponse(false, "Success", filteredData))
            } catch (e: Exception) {
                _uiState.value = UiState.Error(R.string.something_wrong.toString())
            }
        }
    }
}

DaftarWisataRepository.kt :

class DaftarWisataRepository(private val apiService: ApiService) {
    suspend fun getPopular(): DaftarWisataResponse {
        return apiService.daftarWisata(BuildConfig.MY_TOKEN, Constants.PATH_DAFTAR_ALL_WISATA)
    }

    fun searchWisata(query: String, dataWisata: DaftarWisataResponse): List<DataDaftarResponse> {
        val data = dataWisata.data
        return data.filter {
            it.name.contains(query, ignoreCase = true)
        }
    }

    companion object {
        @Volatile
        private var instance: DaftarWisataRepository? = null
        fun getInstance(
            apiService: ApiService
        ): DaftarWisataRepository =
            instance ?: synchronized(this) {
                instance ?: DaftarWisataRepository(apiService)
            }.also { instance = it }
    }
}

下面是错误消息:enter image description here

Kotlin Android-Studio IndexOutOfBoundsException

评论


答: 暂无答案