Данные не будут отображаться при обновлении RecyclerView с ListAdapter - PullRequest
0 голосов
/ 05 ноября 2019

Данные в RecyclerView вызываются в первый раз без проблем. Однако, когда я обновляю данные, по какой-то причине все элементы становятся пустыми.

MainActivity это

class BusinessActivity : AppCompatActivity() {

    private val businessViewModel: BusinessViewModel by viewModel()
    private val imageLoader: ImageLoader by inject()
    private lateinit var staggeredGridLayoutManager: StaggeredGridLayoutManager
    private lateinit var skeleton: Skeleton
    private val adapter: BusinessAdapter by lazy { BusinessAdapter(imageLoader, businessViewModel) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_business)
        initToolbar()
        skeleton = findViewById<SkeletonLayout>(R.id.skeletonLayout)
        staggeredGridLayoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
        staggeredGridLayoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
        recycler_view.apply {
            layoutManager = staggeredGridLayoutManager
            adapter = this@BusinessActivity.adapter
            setHasFixedSize(true)
        }
        setupSkeleton()
        initializeObserverBusiness()
        refreshBusiness.setOnRefreshListener {
            refreshBusiness.isRefreshing = true
            skeleton.showSkeleton()
            businessViewModel.retrieveBusiness()
        }
    }

    private fun initToolbar() {
        setSupportActionBar(toolbar)
        supportActionBar?.title = getString(R.string.app_name)
        this.setSystemBarColor(this)
    }

    private fun setupSkeleton(){
        skeleton = recycler_view.applySkeleton(R.layout.business_card, 6)
        skeleton.showSkeleton()
    }

    private fun initializeObserverBusiness(){
        businessViewModel.uiState.observe(this, Observer {
            val dataState = it ?: return@Observer
            if (!dataState.showProgress){
                refreshBusiness.isRefreshing = false
                skeleton.showOriginal()
            }
            if (dataState.business != null && !dataState.business.consumed){
                dataState.business.consume()?.let { business ->
                    adapter.submitList(business)
                }
            }
            if (dataState.error != null && !dataState.error.consumed){
                dataState.error.consume()?.let { error ->
                    Toast.makeText(this, resources.getString(error), Toast.LENGTH_LONG).show()
                }
            }
        })
    }
}

и Адаптер для RecyclerView , в настоящее время я использую DiffCallback и ListAdapter из-за лучшей производительности.

class BusinessAdapter(var imageLoader: ImageLoader, var viewModel: BusinessViewModel) : ListAdapter<Business, BusinessViewHolder>(DIFF_CALLBACK){
    companion object{
        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Business>() {
            override fun areItemsTheSame(oldItem: Business, newItem: Business) = oldItem.id == newItem.id
            override fun areContentsTheSame(oldItem: Business, newItem: Business) = oldItem == newItem
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = BusinessViewHolder.create(parent)

    override fun onBindViewHolder(holder: BusinessViewHolder, position: Int) {
        holder.bind(getItem(position), imageLoader, viewModel)
    }
}

и ViewHolder для Адаптера

class BusinessViewHolder constructor(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {

    fun bind(business: Business, imageLoader: ImageLoader, viewModel: BusinessViewModel) {
        businessImage?.let { imageLoader.load("${BuildConfig.MY_URL}/gallery/${business.images[0]}", it) }
        ownerBusiness.text = business.owner
        businessName.text = business.name
        cardBusiness.setOnClickListener {
            viewModel.callDetailBusiness(business.id)
        }
    }

    companion object {
        fun create(parent: ViewGroup): BusinessViewHolder {
            return BusinessViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.business_card, parent, false))
        }
    }
}

и ViewModel

class BusinessViewModel (private val businessRepository: BusinessRepository): ViewModel() {
    private val _uiState = MutableLiveData<BusinessDataState>()
    val uiState: LiveData<BusinessDataState> get() = _uiState
    val _showDetailBusiness = MutableLiveData<Int?>()
    val showDetailBusiness: LiveData<Int?> get() = _showDetailBusiness

    init {
        retrieveBusiness()
    }

    fun retrieveBusiness(){
        viewModelScope.launch {
                runCatching {
                    emitUiState(showProgress = true)
                    businessRepository.retrieveBusiness()
                }.onSuccess {
                    emitUiState(business = Event(it))
                }.onFailure {
                    emitUiState(error = Event(R.string.internet_failure_error))
                }
        }
    }

    fun callDetailBusiness(businessId: Int) {
        _showDetailBusiness.value = businessId
    }

    private fun emitUiState(showProgress: Boolean = false, business: Event<List<Business>>? = null, error: Event<Int>? = null){
        val dataState = BusinessDataState(showProgress, business, error)
        _uiState.value = dataState
    }

    data class BusinessDataState(val showProgress: Boolean, val business: Event<List<Business>>?, val error: Event<Int>?)
}

Когда данные загружаются в первый раз, я вижу это,FirstTimeLoad

однако, когда я применяю SwipeRefresh. Я получаю данные.

D / OkHttp: [{"id": 18, "name": "Whatsup", "owner": "Mi Soledad", "category": "ToDo",

, но RecyclerView не будет прикреплять новую информацию ... DataMissing

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...