【问题标题】:RecyclerView Adapter not able to delete all elementsRecyclerView 适配器无法删除所有元素
【发布时间】:2016-11-12 14:06:30
【问题描述】:

我无法找到此问题的有效解决方案,我不知道如何正确表达问题。我正在使用 OpenWeather API 来获取未来 7 天的预测。我为所有与网络相关的网络定义了一个单独的类工作并将结果存储在 sqlite 数据库中,然后将结果字符串附加到回收器视图。我使用改造将我的 HTTP API 转换为 Java 接口。我已将回收器视图适配器从我的 MainFragment 类传递给此类构造函数。我是能够正确地从 api 获取数据但是下面的代码不能正常工作

@Override
    public void onResponse(Call<OpenWeather> call, Response<OpenWeather> response) {
        int code = response.code();
        if (code == 200) {
            OpenWeather openWeather = response.body();
            String []result = getWeatherDataFromRetrofit(openWeather,postal);
            if (mForecastAdapter != null) {
                Log.e(LOG_TAG,""+mForecastAdapter.getItemCount());
                for(int i=0;i<mForecastAdapter.getItemCount();i++){
                    mForecastAdapter.remove(i);
                }
                for(int i=0;i<result.length;i++) {
                    String dayForecastStr = result[i];
                    mForecastAdapter.add(i,dayForecastStr);
                }
                // New data is back from the server.  Hooray!

            }

        } else {
            Toast.makeText(mContext, "Did not work: " + String.valueOf(code), Toast.LENGTH_LONG).show();
        }
    }

retrofit 中异步调用此函数。用于删除 mForecastAdapter 中元素的 for 循环未完全运行,导致列表包含重复项

这是我使用 Recycler View 适配器的删除和添加功能

public void add(int position, String item) {
        mDataset.add(position, item);
        Log.e("Add element:", item);
        notifyItemInserted(position);
    }

    public void remove(int position) {
        Log.e("Remove element:",mDataset.get(position));
        mDataset.remove(position);
        notifyItemRemoved(position);
    }

以下是显示我用于清除 mForecastAdapter 的 for 循环未完全运行的日志条目

应用启动时

E/FetchWeatherTask: 0
E/Add element:: Sun, Jul 10 - Rain - 35/27
E/Add element:: Mon, Jul 11 - Rain - 32/27
E/Add element:: Tue, Jul 12 - Rain - 32/27
E/Add element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Thu, Jul 14 - Rain - 32/26
E/Add element:: Fri, Jul 15 - Rain - 33/27
E/Add element:: Sat, Jul 16 - Rain - 32/27

当我第一次刷新应用程序时

E/FetchWeatherTask: 7
E/Remove element:: Sun, Jul 10 - Rain - 35/27
E/Remove element:: Tue, Jul 12 - Rain - 32/27
E/Remove element:: Thu, Jul 14 - Rain - 32/26
E/Remove element:: Sat, Jul 16 - Rain - 32/27
E/Add element:: Sun, Jul 10 - Rain - 35/27
E/Add element:: Mon, Jul 11 - Rain - 32/27
E/Add element:: Tue, Jul 12 - Rain - 32/27
E/Add element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Thu, Jul 14 - Rain - 32/26
E/Add element:: Fri, Jul 15 - Rain - 33/27
E/Add element:: Sat, Jul 16 - Rain - 32/27

当我第二次刷新应用时

E/FetchWeatherTask: 10
E/Remove element:: Sun, Jul 10 - Rain - 35/27
E/Remove element:: Tue, Jul 12 - Rain - 32/27
E/Remove element:: Thu, Jul 14 - Rain - 32/26
E/Remove element:: Sat, Jul 16 - Rain - 32/27
E/Remove element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Sun, Jul 10 - Rain - 35/27
E/Add element:: Mon, Jul 11 - Rain - 32/27
E/Add element:: Tue, Jul 12 - Rain - 32/27
E/Add element:: Wed, Jul 13 - Rain - 35/27
E/Add element:: Thu, Jul 14 - Rain - 32/26
E/Add element:: Fri, Jul 15 - Rain - 33/27
E/Add element:: Sat, Jul 16 - Rain - 32/27

我无法理解为什么用于删除元素的 for 循环无法正常工作。在此致谢

解决方案:-

int count = mForecastAdapter.getItemCount()
for(int i=0;i<count;i++){
                    mForecastAdapter.remove(i);
                }

或者我可以在 remove() 中一次性清除列表

public void remove() {
            mDataset.clear();
            notifyItemRemoved(position);
        }

【问题讨论】:

  • 你可以试试 notifyDataSetChanged 代替 notifyItemRemoved 吗?
  • 删除数据时int i=mForecastAdapter.getItemCount()-1;i&gt;=0;i-- 怎么样。或者只是调用清除所有项目。
  • 这看起来很奇怪,但是您需要编写更多代码才能找到问题,也许您可​​以尝试使用“清除”来清空数组并使用您的添加函数和调用 notifydatasetchanged when完毕?或者尝试调试看看该项目是否真的被删除了
  • 用于从适配器中删除项目的 for 循环未正确运行,即即使适配器中的元素总数为 10,它也仅运行 3-4 次并且不连续删除元素

标签: java android android-recyclerview adapter retrofit


【解决方案1】:

你的问题在这里:

for(int i=0;i<mForecastAdapter.getItemCount();i++){
    mForecastAdapter.remove(i);
}

基本上,mForecastAdapter.getItemCount() 在 for 循环的每次迭代中都会返回不同的大小,因为您要删除项目并更改其大小。这意味着对于 10 个项目,您既可以增加 i 也可以减少计数,有效地运行循环的次数是您希望的一半。

第二个问题:您在每次迭代时都删除了 ith 项目,但在您删除项目时,Java 中的列表会重新索引。

试试这个:

int count = mForecastAdapter.getItemCount();
for (int i = 0; i < count; ++i) {
    mForecastAdapter.remove(0);
}

【讨论】:

  • 哦,谢谢 thomas,我也在考虑更改删除功能,以便我可以直接清除列表而不是循环
猜你喜欢
  • 1970-01-01
  • 2017-09-06
  • 1970-01-01
  • 2023-03-13
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多