【发布时间】:2020-09-22 21:59:54
【问题描述】:
我有一个视图模型和数据类,它们可以获取 NASA api 以获取火星照片。应该向用户显示来自查询的随机日期的图像。我总是需要返回一个图像 url(照片类中的 imgSrc)。如果没有找到 url (imgSrc),则刷新数据,直到找到并显示。如果用户选择滑动刷新,则此逻辑需要在应用程序启动后以及 swiperefreshlayout 后返回一个 imgSrc。我已经坚持了一个星期没有解决。处理这个问题的最佳方法是什么?即使我必须重构我的代码,我也希望指出正确的方向。
Here is the actual project on github.
视图模型
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dev20.themarsroll.models.MarsPhotos
import com.dev20.themarsroll.models.Photo
import com.dev20.themarsroll.repository.MarsPhotoRepository
import com.dev20.themarsroll.util.Resource
import kotlinx.coroutines.launch
import retrofit2.Response
class MarsPhotoViewModel(
private val marsPhotoRepository: MarsPhotoRepository
): ViewModel() {
val marsPhotos: MutableLiveData<Resource<MarsPhotos>> = MutableLiveData()
init {
getRandomPhotos()
}
fun getCuriosityPhotos(solQuery: Int, roverQuery: Int, camera: String) = viewModelScope.launch {
marsPhotos.postValue(Resource.Loading())
val response = marsPhotoRepository.getCuriosityPhotos(solQuery, roverQuery, camera)
marsPhotos.postValue(handlePhotosResponse(response))
}
private fun handlePhotosResponse(response: Response<MarsPhotos> ) : Resource<MarsPhotos> {
if(response.isSuccessful) {
response.body()?.let { resultResponse ->
return Resource.Success(resultResponse)
}
}
return Resource.Error(response.message())
}
fun getRandomPhotos() {
getCuriosityPhotos((1..2878).random(), 5, "NAVCAM")
}
fun savePhoto(photo: Photo) = viewModelScope.launch {
marsPhotoRepository.upsert(photo)
}
fun getSavedPhotos() = marsPhotoRepository.getSavedPhotos()
fun deletePhoto(photo: Photo) = viewModelScope.launch {
marsPhotoRepository.deletePhoto(photo)
}
}
好奇心碎片
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.View
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.dev20.themarsroll.R
import com.dev20.themarsroll.adapters.MarsPhotoAdapter
import com.dev20.themarsroll.util.Resource
import com.dev20.ui.MarsActivity
import com.dev20.ui.MarsPhotoViewModel
import kotlinx.android.synthetic.main.fragment_curiosity.*
class CuriosityFragment : Fragment(R.layout.fragment_curiosity) {
lateinit var viewModel: MarsPhotoViewModel
lateinit var marsPhotoAdapter: MarsPhotoAdapter
val TAG = "CuriosityFragment"
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = (activity as MarsActivity).viewModel
setupRecyclerView()
swipeLayout.setOnRefreshListener {
viewModel.getRandomPhotos()
swipeLayout.isRefreshing = false
}
marsPhotoAdapter.setOnItemClickListener {
val bundle = Bundle().apply {
putSerializable("photo", it)
}
findNavController().navigate(
R.id.action_curiosityFragment_to_cameraFragment,
bundle
)
}
viewModel.marsPhotos.observe(viewLifecycleOwner, { response ->
when(response) {
is Resource.Success -> {
hideProgressBar()
response.data?.let { curiosityResponse ->
marsPhotoAdapter.differ.submitList(curiosityResponse.photos)
}
}
is Resource.Error -> {
hideProgressBar()
response.message?.let { message ->
Log.e(TAG, "An Error occurred: $message")
}
}
is Resource.Loading -> {
showProgressBar()
}
}
})
}
private fun hideProgressBar() {
curiosityPaginationProgressBar.visibility = View.INVISIBLE
}
private fun showProgressBar() {
curiosityPaginationProgressBar.visibility = View.VISIBLE
}
private fun setupRecyclerView() {
marsPhotoAdapter = MarsPhotoAdapter()
rvCuriosityPhotos.apply {
adapter = marsPhotoAdapter
layoutManager = LinearLayoutManager(activity)
}
}
}
MarsPhoto 数据类
data class MarsPhotos(
val photos: MutableList<Photo>,
val camera: MutableList<Camera>
)
照片数据类
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.google.gson.annotations.SerializedName
import java.io.Serializable
@Entity(
tableName = "photos"
)
@TypeConverters
data class Photo(
@PrimaryKey(autoGenerate = true)
var id: Int? = null,
@SerializedName("earth_date")
val earthDate: String,
@SerializedName("img_src")
val imgSrc: String,
val sol: Int,
@SerializedName("rover_id")
val rover: Int,
) : Serializable
【问题讨论】: