提问者:小点点

Android。屏幕展示片段时,直播数据不展示该数据


我最近开始学习Android,我有一个问题。我在项目中使用了MVVM,协程,实时数据,匕首2,改造。问题是数据没有显示在Recycler视图的Fragment中,而是在更改配置(屏幕旋转)时显示数据。我试图在互联网上找到解决方案。但我发现的并没有导致成功

MainPageFragment

() { // 待办事项:重命名和更改参数类型私有var参数1:字符串?=空私有var参数2:字符串?=空私有lateinit var绑定:FragmentMainPageBind

@Inject
lateinit var factory : ShopAppViewModelFactory
private val viewModel: ShopAppViewModel by lazy {
   ViewModelProvider(this, factory).get(ShopAppViewModel::class.java)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.let {
        param1 = it.getString(ARG_PARAM1)
        param2 = it.getString(ARG_PARAM2)
    }
    component.inject(this)
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    binding = FragmentMainPageBinding.inflate(inflater, container, false)

    val recyclerviewLatestProducts = binding.recyclerViewLatestProduct
    val recyclerviewProductsOnDiscont = binding.recyclerViewProductsOnDiscont

    val adapterLatestProduct = ShopAppRecyclerViewAdapter()
    val adapterProductsOnDiscont = ShopAppRecyclerViewAdapter()

    recyclerviewLatestProducts.adapter = adapterLatestProduct
    recyclerviewProductsOnDiscont.adapter = adapterProductsOnDiscont

    viewModel.getLatestProduct().observe(viewLifecycleOwner, {
        adapterLatestProduct.products = it
    })

    viewModel.getProductOnDiscont().observe(viewLifecycleOwner) {
        adapterProductsOnDiscont.products = it
    }

    viewModel.getDataAboutProductsFromNetwork()

    return binding.root
}

}`

ShopAppViewModel

'class ShopAppViewModel(私有val存储库:存储库):ViewModel(){

private var latestProduct = MutableLiveData<List<Product>>()
private var productOnDiscont = MutableLiveData<List<Product>>()


fun getLatestProduct(): MutableLiveData<List<Product>> {
    return latestProduct
}

fun getProductOnDiscont(): MutableLiveData<List<Product>> {
    return productOnDiscont
}

fun getDataAboutProductsFromNetwork() {

    try {
        viewModelScope.launch {

            val latest = async {
                repository.getLatestProducts()
            }

            val flashSale = async {
                repository.getProductsOnDiscont()
            }

            processData(latest.await(), flashSale.await())
        }

    } catch (e: Exception) {
        Log.e(ContentValues.TAG, e.message.toString())
    }
}

private fun processData(responseGoodsLatest: Response<GoodsLatest>, responseFlashSale: Response<ProductOnDiscount>) {

    val bodyLatest = responseGoodsLatest.body()
    val bodyFlashSale = responseFlashSale.body()

    var listLatest = ArrayList<Product>()
    var listProductOnDiscont = ArrayList<Product>()

    if (responseGoodsLatest.isSuccessful && bodyLatest != null) {
        listLatest = transformLatestToProduct((bodyLatest.latest))
    }

    if (responseFlashSale.isSuccessful && bodyFlashSale != null) {
        listProductOnDiscont = transformDiscontToProduct((bodyFlashSale.flash_sale))
    }

    latestProduct.postValue(listLatest)
    productOnDiscont.postValue(listProductOnDiscont)

}

private fun transformLatestToProduct(latests: List<Latest>): ArrayList<Product> {

    val products = ArrayList<Product>()

    for(latest in latests) {
        products.add(Product.Latest(latest.category, latest.image_url, latest.name, latest.price))
    }

    return products
}

private fun transformDiscontToProduct(flashSales: List<FlashSale>): ArrayList<Product> {

    val products = ArrayList<Product>()

    for(flashSale in flashSales) {
        products.add(Product.FlashSale(flashSale.category, flashSale.discount, flashSale.image_url, flashSale.name, flashSale.price))
    }

    return products
}

}`

商店应用视图模型工厂

'@Suppress("UNCHECKED_CAST")class ShopAppViewModelFactory(私有val存储库:存储库): ViewModelProvider.Factory{

override fun <T : ViewModel> create(modelClass: Class<T>): T {

    if (modelClass.isAssignableFrom(ShopAppViewModel::class.java)) {
        return ShopAppViewModel(repository) as T
    }

    throw IllegalArgumentException("Unknown ViewModel class")
}

}`

商店应用回收r查看适配器

'class ShopAppRecyclerViewAdapter: RecyclerView.Adapter(){

var products = listOf<Product>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShopAppViewHolder {

    return when(viewType) {

        R.layout.recyclerview_latest_element -> ShopAppViewHolder.LatestViewHolder(
            RecyclerviewLatestElementBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
        )

        R.layout.recyclerview_sale_element -> ShopAppViewHolder.FlashSaleViewHolder(
            RecyclerviewSaleElementBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
        )

        else -> throw IllegalArgumentException("Invalid ViewType Provided")
    }
}

override fun onBindViewHolder(holder: ShopAppViewHolder, position: Int) {

    when (holder) {
        is ShopAppViewHolder.LatestViewHolder -> {
            val product = products[position] as Product.Latest
            holder.bind(product)
            Glide.with(holder.itemView.context)
                .load(product.image_url)
                .into(holder.imageView)
        }

        is ShopAppViewHolder.FlashSaleViewHolder -> {
            holder.bind(products[position] as Product.FlashSale)
            val product = products[position] as Product.FlashSale
            holder.bind(product)
            Glide.with(holder.itemView.context)
                .load(product.image_url)
                .into(holder.imageView)
        }
    }
}

override fun getItemCount(): Int = products.size


override fun getItemViewType(position: Int): Int {
    return when(products[position]){
        is Product.Latest -> R.layout.recyclerview_latest_element
        is Product.FlashSale -> R.layout.recyclerview_sale_element
    }
}

}`

ShopAppViewHolder

'密封类ShopAppViewHolder(绑定:视图绑定):RecycliView. ViewHolder(绑定.root){

class LatestViewHolder(private val binding: RecyclerviewLatestElementBinding) : ShopAppViewHolder(binding) {

    val imageView = binding.imageViewBackground

    fun bind(product: Product.Latest) {

        binding.textViewCategory.text = product.category
        binding.textViewName.text = product.name
        binding.textViewPrice.text = product.price.toString()
    }
}

class FlashSaleViewHolder(private val binding: RecyclerviewSaleElementBinding) : ShopAppViewHolder(binding) {

    val imageView = binding.imageViewBackground

    fun bind(product: Product.FlashSale) {

        binding.textViewCategory.text = product.category
        binding.textViewName.text = product.name
        binding.textViewPrice.text = product.price.toString()
        binding.textViewSale.text = product.discount.toString()
    }
}

}`

问题是数据没有显示在Recycler视图的Fragment中,而是在更改配置(屏幕旋转)时显示了数据。我试图在网上找到解决方案。但我发现的并没有导致成功


共1个答案

匿名用户

 viewModel.getLatestProduct().observe(viewLifecycleOwner, {
        adapterLatestProduct.products = it
    })

您不能只设置一个新列表并期望Adapter更新。您必须使用通知fyDataSetChanged()将更改通知Adapter

但是您可以使用ListAdapter来简化适配器。它将管理正确更新列表并为任何更改设置动画(另请参阅DiffCallback以获得更好的更新处理)。

ListAdapter支持您通过LiveData更改数据的方法。提交新数据集时,您只需调用适配器. submitList(dataList)来更新适配器。

   viewModel.getLatestProduct().observe(viewLifecycleOwner, {
            adapterLatestProduct.submitList(it)
        })