当数据更改时,片段内的 RecyclerView 适配器不会更新

RecyclerView adapter inside a fragment is not updating when data changes

我有一个包含 2 个选项卡的 activity,每个选项卡在 ViewPager 中都有一个片段。每个片段都有一个RecyclerView。 当我导航到另一个 activity 时,片段中的数据应该更新。虽然数据被正确发送到片段,但显示的是原始数据。 我尝试在片段中使用 notifyDataSetChanged() 方法,但它没有用。 我还尝试从 activity 调用它,例如:

if (!pickedItemsList.isNullOrEmpty() && notScannedItemsFragment != null && notScannedItemsFragment.isAdded)
{
    notScannedItemsFragment.notScannedItemsAdapter.notifyDataSetChanged()
}

然而,它也没有用。

这就是我启动片段的方式:

override fun initFragments(savedInstanceState: Bundle?, pickedItemsList: ArrayList<OrderDetail>, remainigItemsList: ArrayList<OrderDetail>) {
    val listener: ItemsInteractionListener = object : ItemsInteractionListener {
        override fun onSwipeToRefresh() {
            presenter.onSwipeToRefresh()
        }
    }

    if (!pickedItemsList.isNullOrEmpty() && notScannedItemsFragment != null && notScannedItemsFragment.isAdded) {
        notScannedItemsFragment.notScannedItemsAdapter.notifyDataSetChanged()
        scannedItemsFragment = ScannedItemsFragment().newInstance(remainingItemsList)
        notScannedItemsFragment = NotScannedItemsFragment().newInstance(pickedItemsList)!!
    } else {
         scannedItemsFragment = ScannedItemsFragment().newInstance(arrayListOf())
         notScannedItemsFragment = NotScannedItemsFragment().newInstance(allItemsList)!!
    }
    scannedItemsFragment.setListener(listener)
    notScannedItemsFragment.setListener(listener)
}

allItemList 是原始列表,pickedItemsListremainingItemsList 是更改后的列表(我从另一个 activity 那里得到的)

这是片段之一 类:

class NotScannedItemsFragment : BaseFragment() {

    private var listener: ItemsInteractionListener? = null
    lateinit var notScannedItemsAdapter: OrderItemListingAdapter
    private var itemRemainingCount: Int = 0
    lateinit var notScannedItems: ArrayList<OrderDetail>

    lateinit var recyclerView: RecyclerView

    lateinit var fragmentView: View

    fun newInstance(notScannedItems: ArrayList<OrderDetail>): NotScannedItemsFragment? {
        val notScannedItemsFragment = NotScannedItemsFragment()
        val args = Bundle()
        val order = Gson().toJson(notScannedItems)

        args.putString(IntentConstants.EXTRA_NOT_SCANNED_ITEM_LIST, order)
        notScannedItemsFragment.setArguments(args)

        return notScannedItemsFragment
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val str = arguments?.getString(IntentConstants.EXTRA_NOT_SCANNED_ITEM_LIST)
        notScannedItems = Gson().fromJson(
            str,
            object : TypeToken<List<OrderDetail?>?>() {}.type
        ) as ArrayList<OrderDetail>
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        fragmentView = inflater.inflate(R.layout.fragment_not_scanned_items, container, false)
        recyclerView = fragmentView.notScannedItemListing
        return fragmentView
    }

    fun setListener(listener: ItemsInteractionListener) {
        this.listener = listener
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        setUpRecycler(view)
        super.onViewCreated(view, savedInstanceState)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    }

    private fun setUpRecycler(view: View) {
        imageLoader = ImageLoader(context)

        notScannedItemsAdapter = OrderItemListingAdapter(
            false,
            imageLoader,
            object : ImageClickListener {
                override fun onImageClick(
                    itemName: String,
                    itemQuantity: Int,
                    url: String,
                    barcodes: List<String>?
                ) {
                    startImageFullViewActivity(itemName, itemQuantity, url, barcodes)
                }
            })

        notScannedItemsAdapter.addItem(notScannedItems)

        notScannedItemsAdapter.notifyDataSetChanged()

        view.notScannedItemListing.apply {
            view.notScannedItemListing.layoutManager = LinearLayoutManager(context)
            view.notScannedItemListing.setHasFixedSize(true)
            view.notScannedItemListing.isNestedScrollingEnabled = false
            adapter = notScannedItemsAdapter
        }

        notScannedItemsAdapter.printList()
    }

    fun showOrderItemListing(notScannedItems: ArrayList<OrderDetail>) {
        this.notScannedItems = notScannedItems
        itemRemainingCount = notScannedItems.size


    }

    fun getItemsRemainingCount(): Int{
        return notScannedItems.size
    }

    fun clearItems() {
        notScannedItemsAdapter.clearItems()
    }

    fun updateAdapterContent(pickedItemsList: ArrayList<OrderDetail>) {
        if(this::notScannedItemsAdapter.isInitialized ) {
            notScannedItemsAdapter.clearItems()
            notScannedItemsAdapter.addItem(notScannedItems)
            notScannedItemsAdapter.notifyDataSetChanged()

        }
    }
}

事实证明,因为我是从 arguments 获取列表,所以它没有使用新列表进行更新。如前所述 here如果 Fragment 暂停和恢复,将保留在 onCreate() 中初始化的任何内容。

所以我添加了一个布尔变量 loadListFromArgs 并且我只在 args 为真时从 args 加载列表,当我调用 updateAdapterContent 时我将其设置为 false。