【问题标题】:Adding items to ListView causes first item appear again and again将项目添加到 ListView 会导致第一个项目一次又一次地出现
【发布时间】:2014-03-25 14:19:56
【问题描述】:

当应用启动时,我从设备的 SD 卡中加载一些对象并将它们添加到 ListView。

Objects = new ArrayList<DataObject>();
Items = new ArrayList<MenuItem>();
Adapter = new MenuItemAdapter(this, Items);

listView.setAdapter(Adapter);

LoadObjects();

当我加载对象时,我会反序列化对象,检查它的唯一 ID,如果它已经在对象列表中,则不应添加它。我的方法 LoadObjects 加载尝试加载具有给定扩展名的目录中的所有文件。然后,如果成功,则尝试使用此方法将其加载到 Items 列表中:

private boolean LoadObject(DataObject obj)
{
     for (DataObject do : Objects)
     {
          if (do.GetID().equals(obj.GetId())
              return false;
     }

     boolean added = Objects.add(do);

     if (added)
     {
          Items.add(new MenuItem(do.GetID(), do.GetName());
          Adapter.notifyDataSetChanged();
     }

     return added;
}

当此方法运行“onCreate”时,它工作正常,它会加载所有可以加载并存储在 SD 卡上的对象。当我尝试在此方法之后添加一个时,第一个项目出现在应添加新项目的列表中。我用一个Dialog输入一个新的名字来创建一个新的DataObject,后面会调用LoadObject(new DataObject(name));

我试过了:

  1. 重置项目适配器

  2. 在自定义适配器上添加一个“添加”方法,这样我就不用添加到项目中,而是通过适配器添加适配器。添加(新数据对象(名称))添加到它自己的列表中;我还有一个 SetList 适配器,可以重新创建列表但没有成功。

  3. 跳过 notifyDataSetChanged

  4. 清除了对象列表、项目列表,每次都创建一个新的适配器 - 重新加载所有对象、所有菜单项、重新创建适配器并设置一个新列表 - 都具有相同的结果。

  5. 跳过 LoadObjects() 并让所有新添加的项目出现,第一个是正确的 - 但我稍后添加的任何内容都显示为与 ListView 中的 #1 相同。

我必须使用 FragmentActivity 而不是 ListActivity,因为我需要显示一些对话框。

简单地说,我使用 ListView 来显示 SD 卡中的特定文件,以便以后能够将它们加载到另一个 Activity 中 - 但这阻碍了我添加任何新项目而无需重新启动 Activity 以显示新项目,这意味着我需要能够从一个空列表开始,然后

【问题讨论】:

    标签: android android-listview android-arrayadapter listadapter dynamically-generated


    【解决方案1】:

    可能是因为您使用了具有多个引用的Adapter。尝试重命名并且不要用大写来命名变量。(另请参阅导入列表以查看 Adapter 你在那里有什么)

    【讨论】:

    • 出于好奇,我将它重命名为“listAdapter”,同样的事情发生了。但我刚刚注意到其他东西,写在另一个答案中作为评论......不知道是什么原因造成的。但它开始越来越频繁地重复自己。
    【解决方案2】:

    您的尝试#4 必须成功。给下一个loadObject() 一个机会:

    private boolean LoadObject(DataObject obj)
    {
         for (DataObject do : Objects)
         {
              if (do.GetID().equals(obj.GetID())
                  return false;
         }
    
         Objects.add(obj);
         Items.add(new MenuItem(obj.GetID(), obj.GetName());
         Adapter = new MenuItemAdapter(this, Items);
         listView.setAdapter(Adapter);
    
         return true;
    }
    

    【讨论】:

    • 不起作用。但似乎在添加了一些项目后,列表开始重复。就我而言,如果列表“a”、“b”、“c”、“d”、“e”、“f”中有 6 个项目,并且当我尝试添加“g”时,“a”会再次出现。但这种情况后来又出现了。我刚刚将整个活动重写为加载对象并将对象添加到列表中的最低限度。它只是一个带有 ListView 的 RelativeLayout。
    • 可能equals()DataObject id 有缺陷。顺便说一下 ArrayList add() always returns trueadded 检查已过时。
    • String.equals(anotherString) 是比较两个字符串的方法,而不是 if (string == anotherString) 几乎肯定会返回 false。由于这个错误,我得到了很多错误,因为我通常是一名 C# 程序员,这意味着我必须改变它来修复错误。每当应用此方法时,它都可以检查两个字符串。
    • 但是,我仍然只从 SD 卡加载对象一次,然后每当我添加一个新项目时,这个方法就是所谓的。这意味着我目前没有从 SD 卡重新加载所有新文件,而是在“添加新”对话框之后调用此方法,因此它不应添加已添加的对象。因为所有添加的对象都是新添加的对象。
    • @Deukalion 你可以尝试更新loadObject() 版本。
    【解决方案3】:

    似乎问题是由于 ListView 位于 RelativeLayout 内,虽然我不知道为什么。

    这就是我最初的布局:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <ListView
            android:id="@+id/main_menulist"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </ListView>
    </RelativeLayout>
    

    当我只使用 ListView 创建一个新布局时,问题不再出现:

    <?xml version="1.0" encoding="utf-8"?>
    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main_menulist"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>
    

    我只读过关于不应该将 ListView 放在 ScrollView 中的内容,但我之前使用过这种类型的解决方案(可能不是通过动态添加项目)并且它有效。

    【讨论】:

      猜你喜欢
      • 2019-02-15
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 2013-04-17
      • 2017-07-23
      • 1970-01-01
      相关资源
      最近更新 更多