惊!关于BaseAdapter你可能不知道的真相(多种type的情况下)

在实现一些app的聊天功能的时候,经常要用到一个ListView显示多种布局。很多书本或者教程都有现成的模板代码,就是在BaseAdapter里面,重写getViewTypeCount,getItemViewType,然后就在getView里面判断具体条目的类型,返回对应的View。就好像下面的代码。

惊!关于BaseAdapter你可能不知道的真相(多种type的情况下)
初学的时候非常的不解。代码中对于View 的复用,难道不会造成混乱吗?例如在应该显示左边的聊天气泡的时候,convertView万一是右边聊天气泡的呢?

真相大白

在粗略看了下源码之后,发现其实根本就不会这样,我们已经重写了getViewTypeCount和getItemViewType方法。其实BaseAdapter的实现已经帮我们考虑了这点,在回调getView之前,其实adapter已经知道了我们一共有多少种类型,而且当前回调getView方法的这个item,它的类型是什么,getView回调方法源码的注释是这样的

 /**
     * Get a View that displays the data at the specified position in the data set. You can either
     * create a View manually or inflate it from an XML layout file. When the View is inflated, the
     * parent View (GridView, ListView...) will apply default layout parameters unless you use
     * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
     * to specify a root view and to prevent attachment to the root.
     * 
     * @param position The position of the item within the adapter's data set of the item whose view
     *        we want.
     * @param convertView The old view to reuse, if possible. Note: You should check that this view
     *        is non-null and of an appropriate type before using. If it is not possible to convert
     *        this view to display the correct data, this method can create a new view.
     *        Heterogeneous lists can specify their number of view types, so that this View is
     *        always of the right type (see {@link #getViewTypeCount()} and
     *        {@link #getItemViewType(int)}).
     * @param parent The parent that this view will eventually be attached to
     * @return A View corresponding to the data at the specified position.
     */
    View getView(int position, View convertView, ViewGroup parent);

可以看到convertView被表述为可以重复使用的老版本view,前提是类型是和当前项匹配的。也就可以这样理解,getViewTypeCount返回的值是多少,这个adapter就会存在多少个convertView,所以在getView中,根本不用担心混乱的问题,因为当type不同的时候,回调传入的convertView压根就不是同一个。

虽然这是一个非常简单的问题,但是网上貌似没有关于这个问题的博客,所以就写下来,初学的时候第一次看这书上的代码依葫芦画瓢,这个问题想了很久都想不出来,可能是我天资愚钝吧,虽然现在看来这个根本不算个问题,但还是写下来吧,万一有需要的人看见了呢?