android自定义AdapterView

    相信很多Android开发人员都有用过ListView, GridView,感觉就是设置一些属性,写一个adapter,然后就OK了。但是你有研究过他们的内部实现吗,如果就是只停留在调用API的层面,可算不上好的技术人员呀,兄弟我在这里抛砖引玉,介绍他们的内部实现,希望可以帮助部分朋友。

    ListView, GridView都继承自AbsListView,而AbsListView又继承自AdapterView。android里面使用adapter的view都需要继承自AdapterView,我在这里先从AdapterView讲起,AbsListView我将会在以后的文章中提及。

    在AdapterView中addView和removeView函数无法使用,因为在AdapterView的源码中如下:

    public void addView(View child) {

        throw new UnsupportedOperationException("addView(View) is not supported in AdapterView");

    }

     public void removeView(View child) {

        throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView");

    }

     在AdapterView中添加,删除子view必须通过addViewInLayout,和removeViewInLayout函数。

     如果自定义View,你需要重写onMeasure函数;如果自定义ViewGroup,你还需要重写onLayout函数。因为AdapterView继承自ViewGroup,所以理论上你需要重写onMeasure,和onLayout两个函数。但是通过addViewInLayout和removeViewInLayout这两个函数名称你或许可以猜得出来,他们都需要在onLayout函数中被调用。而且为了避免多次循环子view,所以在我的demo中对子view的测量和位置的放置都写在onLayout函数中。

    通过AdapterView实现类似ListView的控件,有两个功能必须考虑:超出屏幕范围的子view的删除,和对子view的缓存。删除超出屏幕范围的子view,必须要根据子View的位置和坐标偏移量做相应的计算,如果发现一个子View超出屏幕,应该调用removeViewInLayout函数将它删除,将删除的子view缓存在一个集合中。每次调用adapter.getView函数的时候,获取缓存集合中的第一个元素,并且将它从列表中删除,已避免不必要的内存泄露。将从列表中取得的这个缓存的元素传递给adapter.getView的第二个参数。

    兄弟我第一次写技术博客,文笔拙劣,可能还有很多地方没有将清楚,如果有疑惑的朋友可以通过我的邮箱和我联系:[email protected]

    另外我把我的Demo的源码放上来,有需要的朋友可以查看源码。需要说一下,源码中没有添加触屏惯性滚动的功能,这个请朋友们理解下,毕竟时间有限,以后要有时间我会再补充上去。

     下载地址:http://download.csdn.net/detail/liuyunprogramer/9463633


猜你喜欢

转载自my.oschina.net/u/1273706/blog/638778