我最近开始学习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中,而是在更改配置(屏幕旋转)时显示了数据。我试图在网上找到解决方案。但我发现的并没有导致成功
viewModel.getLatestProduct().observe(viewLifecycleOwner, {
adapterLatestProduct.products = it
})
您不能只设置一个新列表并期望Adapter
更新。您必须使用通知fyDataSetChanged()将更改通知Adapter
。
但是您可以使用ListAdapter来简化适配器。它将管理正确更新列表并为任何更改设置动画(另请参阅DiffCallback以获得更好的更新处理)。
ListAdapter支持您通过LiveData更改数据的方法。提交新数据集时,您只需调用适配器. submitList(dataList)
来更新适配器。
viewModel.getLatestProduct().observe(viewLifecycleOwner, {
adapterLatestProduct.submitList(it)
})