BaseAdapter和ArrayAdapter有什么区别?

102

我想知道使用BaseAdapterArrayAdapter的区别。

我一直通过ArrayAdapters实现我的目标。

在实现适配器界面中,它会影响ListView的性能吗?

最后一个问题是,我是否可以使用任何一个这些Adapters来实现与ListView相关的任何操作,或者只有特定的适配器才能使用?


2
ArrayAdapter是BaseAdapter的一个具体子类。你可以在http://developer.android.com/reference/android/widget/ArrayAdapter.html上找到有关ArrayAdapter的更多信息。而BaseAdapter的详细信息可以在http://developer.android.com/reference/android/widget/BaseAdapter.html上找到。 - Raghunandan
5
ArrayAdapter已经被构建好了,我们只需要使用它即可。而BaseAdapter是一种更通用的适配器,需要我们提供实现(在适配器中实现getView()、getcount()等方法)。 - Pragnani
6个回答

113

这里的区别:

  • BaseAdapter 是一个非常通用的适配器,允许你做几乎任何想做的事情。然而,为了使其工作,你需要自己编写更多的代码。
  • ArrayAdapter 是一个更完整的实现,适用于数组或 ArrayList 中的数据。类似地,还有一个相关的 CursorAdapter,如果你的数据在 Cursor 中,应该使用它。它们都扩展了 BaseAdapter

如果你的数据是某种特殊集合中的数据,或者你不想要 ArrayAdapter 提供的默认行为,你可能需要扩展 BaseAdapter 以获取所需的灵活性。

它们的表现实际上取决于你如何实现它们或改变它们的行为。从本质上讲,任何一个都可以同样有效(尤其是考虑到一个 ArrayAdapter 实际上就是一个 BaseAdapter)。

你可以使用任何适配器来做几乎任何想做的事情,但请记住 BaseAdapter 是抽象的,因此不能直接使用它。


3
ArrayAdapter默认提供的行为(如@tanis-7x所述)是列表项中只能有一个TextView,实际上这种行为非常有限。如果每个列表项中有多个控件,则必须使用BaseAdapter并自己完成工作。当然,你仍然可以使用ArrayAdapter,因为ArrayAdapter是一个BaseAdapter - Felix

22

BaseAdapter是抽象的,而ArrayAdapter扩展了BaseAdapter(它是BaseAdapter的一个具体实现)。如果您扩展ArrayAdapter,则继承了所有ArrayAdapter的功能,并且,通过覆盖其实现,可以修改ArrayAdapter的行为。如果您扩展BaseAdapter,则必须实现所有抽象方法,这些方法已经被ArrayAdapter实现。

另外,这会影响ListView的性能吗?

不会。

最后一个问题是,我可以使用这些适配器中的任何一个来完成ListView的任何操作,还是只有特定的适配器才能使用?

如果SDK中提供的实现满足您的需求,为什么需要重写它并重新发明轮子呢?

它们之间的主要区别在于BaseAdapter不能被实例化,而ArrayAdapter可以。


9

回答您的三个问题:

(1) 根据Android文档,BaseAdapter只是许多适配器类型的超类之一,其中之一是ArrayAdapter。还有许多其他从BaseAdapter派生出来的适配器,适用于不同的目的。因此,两者之间的效率差异不大;使用各种子类可以访问不同的函数/方法。

(2) ArrayAdapter的效率取决于类内部正在进行的处理,即位图和其他数据的处理。

(3) 您可能可以想出一种使用不同类型适配器的ListView的方法,但是ArrayAdapter有效的原因是因为构建交互式列表是有意义的。 ArrayAdapter接受一个Array,通常是对象的ArrayList,然后处理它以创建ListView的后备信息。在这个意义上,设置ArrayList--> ArrayAdapter--> ListView在逻辑上是有意义的。


7

BaseAdapter和ArrayAdapter之间的另一个区别是,如果你扩展ArrayAdapter,则必须在子类构造函数中调用超类构造函数。

UserListAdapter extends ArrayAdapter<String>{

   List<String> UserList;
   Context context;

   public UserListAdapter(Context context, int resource,List<String> listUsers) {
     super(context, resource, listUsers);      /* Super class constructor is called */
     UserList = listUsers;
     this.context = context;
   }

}

但是BaseAdapter没有超类。由于BaseAdapter作为所有其他适配器的超类,它不需要超类。

UserListAdapter extends BaseAdapter{

   List<String> UserList;
   Context context;

   public UserListAdapter(Context context, int resource,List<String> listUsers) {
     /* No super class constructor */
     UserList = listUsers;
     this.context = context;
   }

}

不需要在BaseAdapter中指定数据类型,就像ArrayAdapter一样。 例如:ArrayAdapter<String> - John
在扩展ArrayAdapter<T>的类中,也不应该使用List<T> UserList; - Selvin

6
private static final String[] COUNTRIES = new String[]{
            "Afghanistan", "Angola", "Australia", "Bangladesh", "Belgium",
            "Bhutan", "Brazil", "Canada", "China", "Denmark"
    };

ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.countries_list);
textView.setAdapter(adapter);

在这里,我们不能像使用ArrayAdapter一样使用BaseAdapter。


3

BaseAdapter更加简约和可定制。 ArrayAdapter实现了ListAdapter的最一般用途,但有时它们不够用。

然而,几乎所有的事情都可以通过使用ArrayAdapter来实现。如果您的列表已经通过正确使用ArrayAdapter进行工作,那么您将无法从BaseAdapter中获得任何好处。

但是,如果您在ArrayAdapter实现中存储了您的ContextArraysLists,也许您会想切换到BaseAdapter,因为ArrayAdapter已经实现了它们。

无论如何,如果您这样做了,您总是可以删除这些项目,并采用getItem()来获取数组项,getCount()来获取数组大小,以及getContext()来填充您的视图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接