【问题标题】:How to solve duplicate data in recyclerview如何解决recyclerview中的重复数据
【发布时间】:2020-02-19 06:42:53
【问题描述】:

检索数据时,我在RecyclerView 中得到重复的数据项。

我尝试了一些类似NotifyDataSetChanged()setHasStableIds (true) 的方式。但仍然没有成功,我尝试了这种方式(How to solve duplicate data items in recyclerview)但仍然没有成功。

private void loadFirstPage() {
    Log.d(TAG, "loadFirstPage: ");

    callTopRatedMoviesApi().enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
            if (!response.isSuccessful()) {
                Log.e(TAG, "Response Error : " + response.code());
            } else {
                try {
                    JSONObject jsonObject = new JSONObject(response.body().toString());
                    JSONObject dataObject = jsonObject.getJSONObject("data");
                    JSONArray itemsObject = dataObject.getJSONArray("items");
                    modelGetProductSearchList = new ArrayList<>();
                    progressBar.setVisibility(View.GONE);

                    if (itemsObject.length() == 0) {
                        // Set GONE Visibility of TextView
                    } else {
                        for (int a = 0; a <= itemsObject.length(); a++) {
                            JSONObject object = itemsObject.getJSONObject(a);
                            ModelGetProductSearch modelGetProductSearch = new ModelGetProductSearch();
                            modelGetProductSearch.setId(object.getInt("id"));
                            modelGetProductSearch.setName(object.getString("name"));

                            JSONObject sourceObject = object.getJSONObject("source");
                            modelGetProductSearch.setSourceNames(sourceObject.getString("name"));

                            modelGetProductSearchList.add(modelGetProductSearch);
                            adapter.addAll(modelGetProductSearchList);
                            progressBar.setVisibility(View.GONE);
                            tvTidakAdaHasil.setVisibility(View.GONE);
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                if (currentPage <= TOTAL_PAGES && currentPage <= adapter.getItemCount()) adapter.addLoadingFooter();
                else isLastPage = true;
            }
        }

        @Override
        public void onFailure(Call<JsonObject> call, Throwable t) {
            Log.e(TAG, "onFailure: " + t.getMessage());
            tvTidakAdaHasil.setText("Maaf, cek koneksi internet anda dan coba kembali");
            progressBar.setVisibility(View.GONE);
        }
    });
}

private void loadNextPage() {
    Log.d(TAG, "loadNextPage: " + currentPage);

    callTopRatedMoviesApi().enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
            adapter.removeLoadingFooter();
            isLoading = false;

            if (!response.isSuccessful()) {
                Log.e(TAG, "Response Error : " + response.code());
            } else {
                try {
                    JSONObject jsonObject = new JSONObject(response.body().toString());
                    JSONObject dataObject = jsonObject.getJSONObject("data");
                    JSONArray itemsObject = dataObject.getJSONArray("items");
                    modelGetProductSearchList = new ArrayList<>();
                    progressBar.setVisibility(View.GONE);

                    for (int a = 0; a <= itemsObject.length(); a++) {
                        JSONObject object = itemsObject.getJSONObject(a);
                        ModelGetProductSearch modelGetProductSearch = new ModelGetProductSearch();
                        modelGetProductSearch.setId(object.getInt("id"));
                        modelGetProductSearch.setName(object.getString("name"));

                        JSONObject sourceObject = object.getJSONObject("source");
                        modelGetProductSearch.setSourceNames(sourceObject.getString("name"));

                        modelGetProductSearchList.add(modelGetProductSearch);
                        adapter.addAll(modelGetProductSearchList);
                        progressBar.setVisibility(View.GONE);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                if (currentPage != TOTAL_PAGES && currentPage <= adapter.getItemCount()) adapter.addLoadingFooter();
                else isLastPage = true;
            }
        }

        @Override
        public void onFailure(Call<JsonObject> call, Throwable t) {
            Log.e(TAG, "onFailure: " + t.getMessage());
            tvTidakAdaHasil.setText("Maaf, cek koneksi internet anda dan coba kembali");
            progressBar.setVisibility(View.GONE);
        }
    });
}

这是我的适配器

public class AdapterDetailSearch extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int ITEM = 0;
    private static final int LOADING = 1;

    private List<ModelGetProductSearch> modelGetProductSearchList;
    private Context context;

    private boolean isLoadingAdded = false;

    public AdapterDetailSearch(Context context) {
        this.context = context;
        modelGetProductSearchList = new ArrayList<>();
    }

    public List<ModelGetProductSearch> getMovies() {
        return modelGetProductSearchList;
    }

    public void setMovies(List<ModelGetProductSearch> movieResults) {
        this.modelGetProductSearchList = movieResults;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder = null;
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());

        switch (viewType) {
            case ITEM:
                viewHolder = getViewHolder(parent, inflater);
                break;
            case LOADING:
                View v2 = inflater.inflate(R.layout.row_item_progress, parent, false);
                viewHolder = new LoadingVH(v2);
                break;
        }
        return viewHolder;
    }

    @NonNull
    private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
        RecyclerView.ViewHolder viewHolder;
        View viewHolder = inflater.inflate(R.layout.row_item_detail_list, parent, false);
        return new MovieVH(viewHolder);
    }

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

        final ModelGetProductSearch result = modelGetProductSearchList.get(position);

        switch (getItemViewType(position)) {
            case ITEM:
                final MovieVH itemsListVH = (MovieVH) holder;

                // Visible and Invisible set TextView
        }
    }

    @Override
    public int getItemCount() {
        return modelGetProductSearchList == null ? 0 : modelGetProductSearchList.size();
    }

    @Override
    public int getItemViewType(int position) {
        return (position == modelGetProductSearchList.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
    }


   /*
   Helpers
   _________________________________________________________________________________________________
   */

    public void add(ModelGetProductSearch r) {
        modelGetProductSearchList.add(r);
        notifyItemInserted(modelGetProductSearchList.size() - 1);
    }

    public void addAll(List<ModelGetProductSearch> moveResults) {
        for (ModelGetProductSearch result : moveResults) {
            add(result);
        }
    }

    public void remove(ModelGetProductSearch r) {
        int position = modelGetProductSearchList.indexOf(r);
        if (position > -1) {
            modelGetProductSearchList.remove(position);
            notifyItemRemoved(position);
        }
    }

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

    public boolean isEmpty() {
        return getItemCount() == 0;
    }


    public void addLoadingFooter() {
        isLoadingAdded = true;
        add(new ModelGetProductSearch());
    }

    public void removeLoadingFooter() {
        isLoadingAdded = false;

        int position = modelGetProductSearchList.size() - 1;
        ModelGetProductSearch result = getItem(position);

        if (result != null) {
            modelGetProductSearchList.remove(position);
            notifyItemRemoved(position);
        }
    }

    public ModelGetProductSearch getItem(int position) {
        return modelGetProductSearchList.get(position);
    }


   /*
   View Holders
   _________________________________________________________________________________________________
   */

    /**
     * Main list's content ViewHolder
     */
    protected class MovieVH extends RecyclerView.ViewHolder {
        private LinearLayout llContainer;
        private ImageView ivItem;
        private TextView tvItemTitle, tvPriceRegular, tvPriceAfterDiscount, textFrom;

        public MovieVH(View itemView) {
            super(itemView);

            llContainer = itemView.findViewById(R.id.container);
            ivItem = itemView.findViewById(R.id.iv_item);
            textFrom = itemView.findViewById(R.id.tv_from);
        }
    }


    protected class LoadingVH extends RecyclerView.ViewHolder {
        public LoadingVH(View itemView) {
            super(itemView);
        }
    }
}

【问题讨论】:

    标签: java android android-recyclerview


    【解决方案1】:

    您在 for-loop 内的适配器中多次添加相同的列表,这就是它创建重复的原因。将adapter.addAll 移到for loop 之外,如下所示:

    if (itemsObject.length() == 0) {
        // Set GONE Visibility of TextView
    } else {
        for (int a = 0; a < itemsObject.length(); a++) {
            ...
    
            //Remove from here
            /*adapter.addAll(modelGetProductSearchList);
            progressBar.setVisibility(View.GONE);
            tvTidakAdaHasil.setVisibility(View.GONE);*/    
        }
    
        //Add list here
        adapter.addAll(modelGetProductSearchList);
        progressBar.setVisibility(View.GONE);
        tvTidakAdaHasil.setVisibility(View.GONE);
    }
    

    【讨论】:

    • 同意@md-asaduzzaman 的回答。当您从 0 开始循环时,还要从条件中删除 (=),例如 for (int a = 0; a 。
    • @Mr.Robot,不要忘记在两个 FOR 循环中应用更改。
    • @Md.Asaduzzaman 我已将 adapter.addAll 移到 for 循环之外,但数据项仍然重复
    • @Md.Asaduzzaman 谢谢你,这行得通。很抱歉,代码不起作用,显然我放错了模型。
    猜你喜欢
    • 2017-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 2012-06-26
    相关资源
    最近更新 更多