我是Android开发的初学者,当我从Github API获取数据时遇到问题,我有一个详细信息页面可以显示Github用户的详细信息,但当我想显示数据时它总是不起作用
问题是详情页只能显示一次数据,之后就无法再次加载数据了,因为结果的值始终是Result.Loading(false)。这导致每次要打开详细信息页面时都必须重新打开应用程序。
任何人都可以帮助什么使 ResultViewModel.Loading 的值始终等于 false 吗?我需要 ResultViewModel.Loading 为 true 才能从 API 更新新数据
这是我的代码:
// 详细用户活动
@AndroidEntryPoint
class DetailUserActivity : AppCompatActivity() {
private lateinit var binding: ActivityDetailUserBinding
private val viewModel by viewModels<DetailUserViewModel>()
private var isFavorite = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDetailUserBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val item = intent.getParcelableExtra<GithubUser.Item>("userItems")
val username = item?.login ?: "User Not Found"
Log.d("Intent berhasil", "Data berhasil diterima: $item")
viewModel.getUser(username)
viewModel.resultDetailUser.observe(this) { result ->
when (result) {
is ResultViewModel.Success<*> -> {
val data = result.data as GithubDetailUser
val user = data
binding.imageUser.load(user.avatar_url) {
transformations(CircleCropTransformation())
}
binding.fullNames.text = user.name
binding.username.text = user.login
binding.followerCount.text = user.followers.toString()
binding.followingCount.text = user.following.toString()
binding.repositoryCount.text = user.public_repos.toString()
Log.d("Detail User", "Detail User bisa di GET: $item")
}
is ResultViewModel.Error -> {
Toast.makeText(this, result.exception.message.toString(), Toast.LENGTH_SHORT).show()
Log.d("Intent Error", "Data gagal di GET")
}
is ResultViewModel.Loading -> {
binding.progressBar.isVisible = result.isLoading
Log.d("Loading Detail", "${result.isLoading}")
}
}
}
viewModel.getUser(username)
val fragments = mutableListOf<Fragment>(
UserFollower.newInstance(UserFollower.FOLLOWERS),
UserFollower.newInstance(UserFollower.FOLLOWING)
)
val titleTabFragments = mutableListOf(
getString(R.string.follower_tab), getString(R.string.following_tab)
)
val adapter = DetailUserAdapter(this, fragments)
binding.viewPager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = titleTabFragments[position]
}.attach()
binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
if (tab?.position == 0) {
viewModel.getFollowerUser(username)
} else {
viewModel.getFollowingUser(username)
}
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
viewModel.getFollowerUser(username)
viewModel.resultFavoriteAdd.observe(this) {
updateFavoriteButtonColor(true)
}
viewModel.resultFavoriteDelete.observe(this) {
updateFavoriteButtonColor(false)
}
viewModel.findById(item?.id ?: 0) {
viewModel.viewModelScope.launch {
updateFavoriteButtonColor(true )
}
}
binding.favoriteButton.setOnClickListener {
val titleAdd = getString(R.string.notif_title_add)
val titleDelete = getString(R.string.notif_title_delete)
val addMessage = getString(R.string.notif_add_message)
val deleteMessage = getString(R.string.notif_delete_message)
val userId = item
if (userId != null) {
viewModel.viewModelScope.launch {
if (viewModel.isFavorite.value == true) {
Log.d("DetailUserActivity", "isFavorite: $isFavorite")
viewModel.delete(userId)
// viewModel.setFavorite(isFavorite)
updateFavoriteButtonColor(isFavorite)
sendNotif(titleDelete, deleteMessage)
Log.d("DetailUserActivity", "User dengan ID $userId dihapus dari favorit.")
} else {
viewModel.insert(userId)
// viewModel.setFavorite(!isFavorite)
updateFavoriteButtonColor(!isFavorite)
Log.d("DetailUserActivity", "User dengan ID $userId ditambah ke favorit.")
sendNotif(titleAdd, addMessage)
}
}
}
}
private fun updateFavoriteButtonColor(isFavorite: Boolean) {
val colorRes = if (isFavorite) R.color.colorFav else android.R.color.white
val color = ContextCompat.getColor(this, colorRes)
binding.favoriteButton.setColorFilter(color)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId) {
android.R.id.home -> {
finish()
}
}
return super.onOptionsItemSelected(item)
}
}
// 详细用户视图模型
@HiltViewModel
class DetailUserViewModel @Inject constructor(
private val repository: GithubUserRepositoryImpl,
) : ViewModel() {
val resultDetailUser = MutableLiveData<ResultViewModel>()
val resultFavoriteAdd = MutableLiveData<ResultViewModel>()
val resultFavoriteDelete = MutableLiveData<ResultViewModel>()
val resultFollowersUser = MutableLiveData<ResultViewModel>()
val resultFollowingUser = MutableLiveData<ResultViewModel>()
fun getUser(username: String) {
viewModelScope.launch {
flow {
val response = repository.getDetailUserFromGithub(username)
resultDetailUser.value = ResultViewModel.Loading(true)
emit(response)
}.onCompletion {
resultDetailUser.value = ResultViewModel.Loading(false)
} .catch {
Log.e("Error ", it.message.toString())
it.printStackTrace()
resultDetailUser.value = ResultViewModel.Error(it)
} .collect {
// Ubah tipe data yang dikirimkan ke resultSuccess.value
resultDetailUser.value = ResultViewModel.Success(it)
}
}
}
fun getFollowerUser(username: String) {
viewModelScope.launch {
flow {
resultFollowersUser.value = ResultViewModel.Loading(true)
val response = repository.getFollowerUserFromGithub(username)
emit(response)
} .onStart {
resultFollowersUser.value = ResultViewModel.Loading(true)
} .onCompletion {
resultFollowersUser.value = ResultViewModel.Loading(false)
} .catch {
Log.e("Error ", it.message.toString())
it.printStackTrace()
resultFollowersUser.value = ResultViewModel.Error(it)
} .collect {
// Ubah tipe data yang dikirimkan ke resultSuccess.value
resultFollowersUser.value = ResultViewModel.Success(it)
}
}
}
fun getFollowingUser(username: String) {
viewModelScope.launch {
flow {
resultFollowingUser.value = ResultViewModel.Loading(true)
val response = getFollowingUser(username)
emit(response)
} .onStart {
resultFollowingUser.value = ResultViewModel.Loading(true)
} .onCompletion {
resultFollowingUser.value = ResultViewModel.Loading(false)
} .catch {
Log.e("Error ", it.message.toString())
it.printStackTrace()
resultFollowingUser.value = ResultViewModel.Error(it)
} .collect {
// Ubah tipe data yang dikirimkan ke resultSuccess.value
resultFollowingUser.value = ResultViewModel.Success(it)
}
}
}
}
// 结果视图模型
sealed class ResultViewModel {
data class Success<out T>(val data: T) : ResultViewModel()
data class Error(val exception: Throwable) : ResultViewModel()
data class Loading(val isLoading: Boolean) : ResultViewModel()
}
您面临的问题似乎与 DetailUserViewModel 中的 LiveData 未正确更新有关,请改为执行此操作
fun getUser(username: String) {
viewModelScope.launch {
resultDetailUser.value = ResultViewModel.Loading(true)
flow {
val response = repository.getDetailUserFromGithub(username)
emit(response)
}.onCompletion {
resultDetailUser.value = ResultViewModel.Loading(false)
} .catch {
Log.e("Error ", it.message.toString())
it.printStackTrace()
resultDetailUser.value = ResultViewModel.Error(it)
} .collect {
// Ubah tipe data yang dikirimkan ke resultSuccess.value
resultDetailUser.value = ResultViewModel.Success(it)
}
}
}