首页 > 解决方案 > android recyclerview 选择跟踪器动态数据

问题描述

我已经使用 selection-tracker api 实现了多选的回收视图。

第一个数据列表正常工作,但是当有不同大小的新数据时,就会出现问题。我尝试在每次加载时创建新的跟踪器,但完全失败了。

问题是,当从 api 刷新 listdata 时,ItemKeyProvider.class#getPosition()返回 null。

如何使用动态数据实现选择跟踪器以避免此问题?

private void loadPurchaseOrders(ArrayList<PurchaseOrder> newPurchaseOrders) {
        purchaseOrders.clear();
        purchaseOrders.addAll(newPurchaseOrders);

        if (purchaseOrderRecyclerAdapter == null) {
            /* if (workOrderRecyclerAdapter == null) {*/
            purchaseOrderRecyclerAdapter = new PurchaseOrderRecyclerAdapter(getPurchaseOrders(),
                    statusId,
                    purchaseOrder -> getPurchaseOrderDetail(CURRENT_STATE, purchaseOrder));

            LinearLayoutManager layoutManager = new LinearLayoutManager(this,
                    LinearLayoutManager.VERTICAL, false);
            binding.rvPo.setLayoutManager(layoutManager);
            binding.rvPo.setAdapter(purchaseOrderRecyclerAdapter);

            selectionTrackerBuilder = new SelectionTracker.Builder<>(
                    new Random().toString(),//unique id
                    binding.rvPo,
                    new POItemKeyProvider(getPurchaseOrders()),
                    new POItemDetailsLookup(binding.rvPo),
                    StorageStrategy.createStringStorage());

            selectionTracker = selectionTrackerBuilder.build();

            purchaseOrderRecyclerAdapter.setSelectionTracker(selectionTracker);
        } else {

            purchaseOrderRecyclerAdapter.notifyDataSetChanged();

        }

POItemKeyProvider.class

private static class POItemKeyProvider extends ItemKeyProvider<String> {

    private final Map<String, Integer> mKeyToPosition;
    private List<PurchaseOrder> mPokemonList;

    POItemKeyProvider(List<PurchaseOrder> pokemonList) {
        super(SCOPE_CACHED);
        mPokemonList = pokemonList;

        mKeyToPosition = new HashMap<>(mPokemonList.size());
        int i = 0;
        for (PurchaseOrder pokemon : pokemonList) {
            mKeyToPosition.put(pokemon.getOrderNo(), i);
            i++;
        }
    }

    @Nullable
    @Override
    public String getKey(int i) {
        return mPokemonList.get(i).getOrderNo();// directly from position to key
    }

    @Override
    public int getPosition(@NonNull String s) {
        return mKeyToPosition.get(s);
    }
}

POItemDetailsLookup.class

private static class POItemDetailsLookup extends ItemDetailsLookup<String> {
        RecyclerView mRecyclerView;

        POItemDetailsLookup(RecyclerView recyclerView) {
            this.mRecyclerView = recyclerView;
        }

        @Nullable
        @Override
        public ItemDetails<String> getItemDetails(@NonNull MotionEvent motionEvent) {
            View view = mRecyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
            if (view != null) {
                RecyclerView.ViewHolder viewHolder = mRecyclerView.getChildViewHolder(view);
//                int position = viewHolder.getAdapterPosition();
                if (viewHolder instanceof PurchaseOrderRecyclerAdapter.ViewHolder) {
                    return ((PurchaseOrderRecyclerAdapter.ViewHolder) viewHolder).getItemDetails(motionEvent);
                }
            }
            return null;
        }
    }

标签: androidandroid-recyclerview

解决方案


此实现应使用动态数据:

https://github.com/ExpensiveBelly/RecyclerViewSelection

因为这:

override fun submitList(list: List<T>?) {
        super.submitList(list)
        tracker.deselectIfItemsNotFound(currentList)
    }

推荐阅读