【问题标题】:Getting all of the items from an ArrayAdapter从 ArrayAdapter 获取所有项目
【发布时间】:2012-07-25 12:50:27
【问题描述】:

我有一个由ArrayAdapter 支持的ListFragment,它由Loader 填充。当用户单击其中一个项目时,我想将对选定项目的引用以及列表项的其余部分传递给另一个片段。我的问题是我应该如何从适配器中获取所有项目?以下是我看到的可能性:

1.保留对支持List

的引用

像这样创建适配器:

List<DomainObject> items = new ArrayList<DomainObject>();
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine, items);

然后简单地将items 或它的副本传递给下一个活动。

我看到的缺点是我依赖于未记录的事实,即我传递给构造函数的同一个列表包含稍后的项目。

2。遍历适配器

当一个项目被点击时,遍历适配器并建立列表。这似乎是不必要的工作量。这些项目包含在适配器的List 中,我手动将每个项目复制到一个新列表中。

3。添加到适配器时保留单独的项目列表

在向适配器添加项目之前,将其添加到我在片段中维护的单独列表中。这也很浪费,因为项目列表被复制到ArrayAdapter 和片段中。

【问题讨论】:

    标签: android


    【解决方案1】:

    我玩游戏有点晚了,但我遇到了类似的问题。

    处理#1 的一种方法是在ArrayAdapter 的子类中维护对列表的引用,以便您的重用由适配器对象控制。

    类似:

    public class DomainAdapter extends ArrayAdapter<DomainObject> {
    
        private final List<DomainObject> items;
    
        public DomainAdapter(Context context, List<DomainObject> items) {
            super(context, R.layout.mine, items);
            this.items = items;
        }
    
        public List<DomainObject> getItems() {
            return items;
        }
    }
    

    【讨论】:

    • 注意。如果您计划在某个时候过滤适配器,则此方法可能会失败。执行过滤器将在 ArrayAdapter 内部创建一个全新的 List 实例。这意味着您外部定义的 items 将不再是同一个列表。这意味着如果稍后进行修改,它将不同步。你可以在这里阅读更多信息:jaysoyer.com/2014/07/constructor-woes-androids-arrayadapter
    【解决方案2】:

    我在此期间采用的解决方案就是不使用ArrayAdapter。在您与此 API 作斗争的情况下,似乎最好只使用功能较少(且复杂)的BaseAdapter。您可以在本文中阅读更多关于使用BaseAdapter 而不是ArrayAdapter 的决定:Android Adapter Good Practices

    【讨论】:

    • 虽然那篇文章大部分都不错,但我会忽略他的整个线程安全部分。他完全错误地认为为什么会有锁(由于发生在后台线程上的过滤),并且如果在 UI 线程之外的任何东西上调用 notifyDataSetChanged()ArrayAdapter 已经崩溃。
    • @scompt.com 我认为您发布的链接解释 ArrayAdapter 是错误的。它似乎只解释了 ArrayAdapter。我有点困惑...
    • 从您链接的页面...“只能显示文本。” => 错了。 “强制您提供 CharSequence 项目列表...”=> 错误“要求您提供仅包含 TextView 的布局资源”=> 错误。几乎所有的假设都是错误的......我并不是说 ArrayAdapter 比 BaseAdapter 更好,但基础是错误的。
    • Piwaï 未找到!
    【解决方案3】:

    快速测试表明方法 1 有效。它似乎是最快和最干净的,但由于它没有记录,您可能希望在预期的平台上测试它,并在它们更新时进行测试,以防 ArrayAdapter 的底层结构发生变化。

    我正在使用编译 SDK 版本 22 和最小 SDK 版本 10。

    【讨论】:

      【解决方案4】:

      最好的方法是“保留对列表的引用”但不将“项目”变量/参数传递给构造函数:

      List<DomainObject> items = new ArrayList<DomainObject>(); listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine);

      通过这种方式,您只需将 ArrayList 实例化为一个空数组,您必须自己管理您的列表。

      【讨论】:

        【解决方案5】:

        我认为第一种方法是最好的方法。

        我不认为,数据将是另一个活动的原始数据。因为,您将通过 bundle 传递项目,所以对象首先写入 bundle,然后在我们从 bundle 读取的下一个 Activity 中。

        但是,如果您使用其他方式传递列表,请使用list.clone() 创建新对象,而不是传递原始对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-02
          • 2019-11-07
          • 1970-01-01
          • 1970-01-01
          • 2015-06-02
          相关资源
          最近更新 更多