recyclerview即使在数据集更改时也不引用

0s7z1bwu  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(271)

我正在尝试用recyclerview实现分页。我不知道为什么,但是只有当有结果响应时数据才会刷新,而没有结果它不会更新;筛选和排序工作正常,但位置选择不工作,因为它api为某些选择返回空列表。我在布局中也有swiperefreshlayout,当我再次使用swipe refresh刷新时,recyclerview更新之后。
这是我的分页侦听器和回收视图

public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {

    LinearLayoutManager layoutManager;

    public PaginationScrollListener(LinearLayoutManager layoutManager) {
        this.layoutManager = layoutManager;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        int visibleItemCount = layoutManager.getChildCount();
        int totalItemCount = layoutManager.getItemCount();
        int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();

        if (!isLoading() && !isLastPage()) {
            if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
                    && firstVisibleItemPosition >= 0
                    && totalItemCount >= getTotalPageCount()) {
                loadMoreItems();
            }
        }
    }

    protected abstract void loadMoreItems();

    public abstract int getTotalPageCount();

    public abstract boolean isLastPage();

    public abstract boolean isLoading(); }

这是我的回收视图

GridLayoutManager gridLayoutManager = new GridLayoutManager(getmContext(), AppConstants.GRID_2);
    mProductRecyclerView.setLayoutManager(gridLayoutManager);
    mProductRecyclerView.setItemAnimator(new DefaultItemAnimator());

    PaginationScrollListener paginationScrollListener = new PaginationScrollListener(gridLayoutManager) {
        @Override
        protected void loadMoreItems() {
            isLoading = true;
            //Increment page index to load the next one
            CURRENT_PAGE += 1;
            loadNextPage();
        }

        @Override
        public int getTotalPageCount() {
            return TOTAL_PAGE;
        }

        @Override
        public boolean isLastPage() {
            return isLastPage;
        }

        @Override
        public boolean isLoading() {
            return isLoading;
        }
    };

    productListAdapter = new ProductListAdapter(getmContext(), R.layout.b_item_home_product);
    productListAdapter.setiAdapterItemCheckChangeListener(this);
    mProductRecyclerView.setAdapter(productListAdapter);

    mProductRecyclerView.addOnScrollListener(paginationScrollListener);

    itemClickDisposable = productListAdapter.getItemClickSubject().subscribe(productId -> {
        UIHelper.getInstance().switchActivity(getmActivity(), ProductInfoActivity.class, UIHelper.ActivityAnimations.LEFT_TO_RIGHT, productId.toString(), AppConstants.K_ID, false);
    });

    viewModel.getProductsLiveData().observe(getViewLifecycleOwner(), responseList -> {
        switch (responseList.status) {
            case LOADING:
                if (CURRENT_PAGE <= TOTAL_PAGE) {
                    showHideBottomProgress(true);
                } else {
                    isLastPage = true;
                }
                if (isFirstPage) {
                    showMainLoading(true);
                }
                break;
            case ERROR:
                swipeRefreshLayout.setRefreshing(false);
                if (CURRENT_PAGE <= TOTAL_PAGE) {
                    showHideBottomProgress(false);
                }
                if (isFirstPage) {
                    showMainLoading(false);
                } else {
                    isLoading = false;
                }
                showErrorPrompt(responseList.message);
                break;
            case SUCCESS:
                swipeRefreshLayout.setRefreshing(false);
                if (CURRENT_PAGE <= TOTAL_PAGE) {
                    showHideBottomProgress(false);
                }
                if (isFirstPage) {
                    showMainLoading(false);
                } else {
                    isLoading = false;
                }
                productListAdapter.addProducts(responseList.response);
                break;
        }
    });

用于使用此方法加载页面和下一页

private void loadFirstPage() {
    isFirstPage = true;
    isLastPage = false;
    resetProductsList();
    viewModel.getProducts(getProductFilter());
}

private void loadNextPage() {
    isFirstPage = false;
    productFilter.setOffset(CURRENT_PAGE);
    viewModel.getProducts(productFilter);
}

public void resetProductsList() {
    productListAdapter.clear();
    productFilter.setOffset(1);

}

这是我的适配器类

public class ProductListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_SALE = 1, TYPE_POPULAR = 2, TYPE_LOADING = 3;
    private Context mContext;
    private int mResId;
    private List<Product> products;
    private PublishSubject<Integer> itemClickSubject = PublishSubject.create();
    private IAdapterItemCheckChangeListener iAdapterItemCheckChangeListener;
    private IAdapterItemClickListener iAdapterItemClickListener;

    public ProductListAdapter(Context context, int resId, List<Product> data) {
        mContext = context;
        mResId = resId;
        products = data;
    }

    public ProductListAdapter(Context context, int resId) {
        mContext = context;
        mResId = resId;
        products = new ArrayList<>();
    }

    public List<Product> getProducts() {
        return products;
    }

    public void addProducts(List<Product> newProducts) {
        for (Product product : newProducts) {
            addProduct(product);
        }
    }

    public void addProduct(Product newProduct) {
        products.add(newProduct);
        notifyItemInserted(products.size() - 1);
    }

    public void setiAdapterItemCheckChangeListener(IAdapterItemCheckChangeListener iAdapterItemCheckChangeListener) {
        this.iAdapterItemCheckChangeListener = iAdapterItemCheckChangeListener;
    }

    public void setiAdapterItemClickListener(IAdapterItemClickListener iAdapterItemClickListener) {
        this.iAdapterItemClickListener = iAdapterItemClickListener;
    }

    public PublishSubject<Integer> getItemClickSubject() {
        return itemClickSubject;
    }

    // Clean all elements of the recycler

    public void clear() {
        while (getItemCount() > 0) {
            remove(getItem(0));
        }
    }

    public void remove(Product product) {
        int position = products.indexOf(product);
        if (position > -1) {
            products.remove(position);
            notifyItemRemoved(position);
        }
    }

    public Product getItem(int position) {
        return products.get(position);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_SALE:
                return new SaleHolder(LayoutInflater.from(mContext).inflate(R.layout.item_home_sale, parent, false));
            case TYPE_LOADING:
                return new ProgressItemHolder(LayoutInflater.from(mContext).inflate(R.layout.item_pagination, parent, false));
            default:
                return new ProductHolder(LayoutInflater.from(mContext).inflate(mResId, parent, false));
        }

    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        if (getItemViewType(position) == TYPE_POPULAR) {
            ((ProductHolder) holder).setUpProductHolder(products.get(position));
        } else if (getItemViewType(position) == TYPE_LOADING) {
        } else {
            ((SaleHolder) holder).setupSaleHolder(products.get(position));
        }

    }

    @Override
    public int getItemViewType(int position) {

        if (products.get(position).getType() == AppConstants.PRODUCT_TYPE.TYPE_SALE) {
            return TYPE_SALE;
        } else {
            return TYPE_POPULAR;
        }
    }

    @Override
    public int getItemCount() {
        return products.size();
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        itemClickSubject.onComplete();

    }

    public class SaleHolder extends RecyclerView.ViewHolder {

        public SaleHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        private void setupSaleHolder(Product product) {

        }
    }

    public class ProgressItemHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.progress_wheel)
        ProgressWheel progressWheel;
        @BindView(R.id.tv_error)
        TextView errorMsg;

        public ProgressItemHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        private void bindHolder(NetworkState networkState) {
            if (networkState != null && networkState.getStatus() == NetworkState.Status.LOADING) {
                progressWheel.setVisibility(View.VISIBLE);
                progressWheel.spin();
            } else {
                progressWheel.setVisibility(View.GONE);
                progressWheel.stopSpinning();
            }

            if (networkState != null && networkState.getStatus() == NetworkState.Status.FAILED) {
                errorMsg.setVisibility(View.VISIBLE);
                errorMsg.setText(R.string.please_connect_to_your_network);
            } else {
                errorMsg.setVisibility(View.GONE);
            }
        }

    }

    public class ProductHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
        @BindView(R.id.iv_product_preview_image)
        ImageView productImage;
        @BindView(R.id.tv_product_name)
        TextView productName;
        @BindView(R.id.tv_product_price)
        MagicText productPrice;
        @BindView(R.id.tv_average_rating)
        TextView productRating;
        @BindView(R.id.cb_wishlist)
        CheckBox wishlist;
        @BindView(R.id.tv_product_quality)
        TextView productQuality;
        @BindView(R.id.tv_discount)
        TextView discount;
        @BindView(R.id.container_original_price)
        ConstraintLayout originalPrice;
        @BindView(R.id.tv_original_price)
        TextView priceWithoutDiscount;
        @BindView(R.id.tv_brand_name)
        TextView brandName;

        public ProductHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
            RxView.clicks(itemView)
                    .map(unit -> getAdapterPosition())
                    .subscribe(itemClickSubject);
            wishlist.setOnCheckedChangeListener(this);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (iAdapterItemCheckChangeListener == null) return;
            if (buttonView.isPressed()) {
                iAdapterItemCheckChangeListener.onCheckChange(isChecked, getAdapterPosition());
            }
        }

        public void setUpProductHolder(Product product) {
            try {
                productImage.setImageDrawable(null);

                if (product.getBrandLabel() == null) {
                    brandName.setText("");

                } else {
                    brandName.setText(product.getBrandLabel());
                }
                productName.setText(mContext.getString(R.string.product_full_name, product.getName()));

                wishlist.setChecked(product.getWishList() >= 1);

//                productPrice.setText(mContext.getString(R.string.price_with_currency, product.getPrice()));

                float avgRating = product.getAverageRating() != null ? product.getAverageRating() : AppConstants.DEFAULT_RATING;
                String ratingTrimed = String.format(Locale.getDefault(), "%.1f", avgRating);
                productRating.setText(mContext.getString(R.string.average_rating, avgRating));
                productQuality.setText(product.getQuality() != null ? product.getQuality() : "");

                if (product.getDiscount() > 0) {
                    String fullPrice = mContext.getString(R.string.price_in_currency, product.getFinalPrice());
                    productPrice.change(fullPrice, mContext.getResources().getColor(R.color.colorBlack), 16, "normal", product.getFinalPrice());

                    discount.setVisibility(View.VISIBLE);
                    discount.setText(mContext.getString(R.string.discount_with_percent, product.getDiscount()));
                    originalPrice.setVisibility(View.VISIBLE);
                    priceWithoutDiscount.setText(product.getPrice());

                } else {
                    String fullPrice = mContext.getString(R.string.price_in_currency, product.getPrice());
                    productPrice.change(fullPrice, mContext.getResources().getColor(R.color.colorBlack), 16, "normal", product.getPrice());

                    discount.setVisibility(View.GONE);
                    originalPrice.setVisibility(View.GONE);
                }
                if (product.getFree() > 0) {
                    String fullPrice = mContext.getString(R.string.price_in_currency, product.getSpecialPrice());
                    productPrice.change(fullPrice, mContext.getResources().getColor(R.color.colorBlack), 16, "normal", product.getSpecialPrice().toString());

                    originalPrice.setVisibility(View.VISIBLE);
                    priceWithoutDiscount.setText(product.getPrice());

                    discount.setVisibility(View.VISIBLE);
                    discount.setText(mContext.getString(R.string.discount_with_percent, AppConstants.DISCOUNT_100));
                }
                Glide.with(mContext).load(product.getImages().get(0).getValue()).apply(new RequestOptions()
                        .error(R.drawable.no_image_available)
                        .centerCrop().placeholder(R.drawable.no_image_available)).diskCacheStrategy(DiskCacheStrategy.RESOURCE).into(productImage);

            } catch (Exception e) {
                Log.d(getClass().getSimpleName(), "error");
            }
        }

        @Override
        public void onClick(View v) {
            if (iAdapterItemClickListener == null) return;
            iAdapterItemClickListener.onAdapterItemClick(v, getAdapterPosition());
        }
    }

}

这里我实现分页图像预览分页
编辑1:加载第一页时
{“discount”:false,“limit”:10,“offset”:1,“order”:“desc”,“sort”:“rating”}响应:加载第一页时
加载下一页时
{“城市”:“哈萨克斯坦”,“折扣”:假,“限制”:10,“偏移”:1,“顺序”:“描述”,“排序”:“评级”}
响应:当用其他过滤器再次加载页面时

t9eec4r0

t9eec4r01#

我不太明白这个问题。可能是和线程有关的问题。
问题:分页屏幕是一个片段,位置微调器在工具栏中处于活动状态。我用的是 getActivity.findViewById() 获取微调器并填充片段本身中的数据。我为spinner设置了一个侦听器,所以每当单击项时,我都在调用片段中的api。
我已经通过使用事件总线与片段通信解决了这个问题。现在我在活动本身中填充微调器。每当从该微调器单击项目时,我就触发事件;我在实现分页的片段中订阅了这个事件,因此调用了事件api。现在一切正常。

f5emj3cl

f5emj3cl2#

根据适配器类编码部分,您没有处理空列表。
在下面的方法中,您将逐个向适配器的产品列表添加产品。当列表为空时,循环将不工作,并且列表不会更改,因此值与以前的响应相同。

public void addProducts(List<Product> newProducts) {
    for (Product product : newProducts) {
        addProduct(product);
    }
 }

在方法中添加以下代码段

public void addProducts(List<Product> newProducts) {
     if(newProducts!= null && !newProducts.isEmpty()){
       for (Product product : newProducts) 
         addProduct(product);
     }else{
        // either you can set empty list
        this.products = newProducts;
       //or you can clear the list values
       products.clear();
       notifyDataSetChanged();
     }
 }

相关问题