Android中ViewAllFragment重开时GridView列表数据重复问题求助
Android GridView 重复加载数据问题解决
问题描述
关闭ViewAllFragment并重新打开后,GridView中的列表会反复加载相同数据,导致内容重复。已尝试在Fragment销毁时清空Adapter列表、仅当Adapter为空时提交数据,但未解决问题。
相关代码
XML布局
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.view_all.ViewAllFragment"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" android:background="@color/lightGray" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <GridView android:id="@+id/gridView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/lightGray" android:verticalSpacing="1dp" android:horizontalSpacing="1dp" android:visibility="gone" tools:visibility="visible" android:numColumns="auto_fit" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
GridProductAdapter代码
class GridProductAdapter : BaseAdapter() { private var productScrollModelList = arrayListOf<HorizontalProductScrollModel>() fun submitList(productScrollModelList: List<HorizontalProductScrollModel> ){ this.productScrollModelList.addAll(productScrollModelList) notifyDataSetChanged() Log.d(TAG, "submitList: size ${productScrollModelList.size}") } fun clearList(){ this.productScrollModelList.clear() notifyDataSetChanged() } override fun getCount(): Int { return productScrollModelList.size } override fun getItem(i: Int): Any? { return null } override fun getItemId(i: Int): Long { return 0 } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { var localConvertView: View? = convertView val binding: HorizontalScrollItemLayoutBinding if (localConvertView == null) { binding = HorizontalScrollItemLayoutBinding.inflate( LayoutInflater.from(parent.context) ) localConvertView = binding.root localConvertView.setTag(R.id.viewBinding, binding) } else { binding = localConvertView.getTag(R.id.viewBinding) as HorizontalScrollItemLayoutBinding } Glide.with(binding.root.context) .load(productScrollModelList[position].productImage) .placeholder(R.drawable.placeholder_image) .into(binding.hsProductImage) binding.hsProductName.text = productScrollModelList[position].productName binding.hsProductDescription.text = productScrollModelList[position].productDescription binding.hsProductPrice.text = "Rs.${productScrollModelList[position].productPrice}/-" return localConvertView } }
ViewAllFragment代码
private var _binding: FragmentViewAllBinding? = null private val binding get() = _binding!! private val LAYOUT_CODE = 0 private val wishList= arrayListOf<WishListModel>() private val wishlistAdapter = WishlistAdapter(false) private val args by navArgs<ViewAllFragmentArgs>() private var layoutCode:Int =0 private val gridProductAdapter by lazy { GridProductAdapter() } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentViewAllBinding.inflate(inflater) layoutCode = args.layoutCode (requireActivity() as MainActivity).fragmentTitleAndActionBar(args.title) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) if(layoutCode == 0) { wishList.addAll(args.viewAllProductList!!) wishlistAdapter.asyncListDiffer.submitList(wishList) binding.recyclerView.apply { visibility = View.VISIBLE layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL,false) adapter = wishlistAdapter } }else if(layoutCode == 1) { binding.gridView.visibility = View.VISIBLE binding.gridView.adapter = gridProductAdapter Log.d(TAG, "onViewCreated: horizontalProductScrollModelList size ${args.horizontalProductScrollModelList.size}") if(gridProductAdapter.isEmpty) { gridProductAdapter.submitList(args.horizontalProductScrollModelList.toList()) } } } override fun onDestroyView() { super.onDestroyView() gridProductAdapter.clearList() _binding = null }
问题根源及解决方案
1. Adapter提交数据逻辑错误
GridProductAdapter的submitList方法使用addAll追加数据,而非替换原有数据,导致每次调用都会重复添加相同内容。
修复代码:
修改submitList方法,先清空原有列表再添加新数据:
fun submitList(productScrollModelList: List<HorizontalProductScrollModel> ){ this.productScrollModelList.clear() this.productScrollModelList.addAll(productScrollModelList) notifyDataSetChanged() Log.d(TAG, "submitList: size ${productScrollModelList.size}") }
2. 空列表判断无效
ViewAllFragment中使用gridProductAdapter.isEmpty判断,但GridProductAdapter未定义该属性,导致判断逻辑不生效,每次都会执行submitList。
修复代码:
在GridProductAdapter中添加isEmpty属性:
val isEmpty: Boolean get() = productScrollModelList.isEmpty()
或直接在Fragment中用gridProductAdapter.count == 0替代判断条件。
3. Fragment生命周期适配
若Fragment是通过hide/show方式管理而非replace,onDestroyView不会被调用,导致clearList无法执行。此时可在onViewCreated中先清空列表再提交数据,无需判断:
else if(layoutCode == 1) { binding.gridView.visibility = View.VISIBLE binding.gridView.adapter = gridProductAdapter Log.d(TAG, "onViewCreated: horizontalProductScrollModelList size ${args.horizontalProductScrollModelList.size}") gridProductAdapter.clearList() // 先清空 gridProductAdapter.submitList(args.horizontalProductScrollModelList.toList()) }
内容的提问来源于stack exchange,提问作者Dr Mido
相关产品推荐
相关产品推荐

