Android开源代码解读-基于SackOfViewAdapter类实现类似状态通知栏的布局
一般来说,ListView的列表项都会采用相同的布局,只是填充的内容不同而已,这种情况下,Android提供了convertView帮我们缓存列表项,达到循环利用的目的,开发者也会使用ViewHolder模式来对ListView进行优化。但有的情况下,ListView的列表项布局是不尽相同的,甚至差别很大,这时就不能简单的使用同一个布局资源文件来表示不同类型的列表项了,而是必须区别对待。典型的情况如Android状态通知栏,如下图所示。
360安全卫士、唱吧,闪推这三款应用在状态通知栏的布局差别很大,那么我们又想使用同一个Adapter来表示不同列表项,这时就需要在Adapter中使用容器来包含这些不同的View了。这里定义SackOfViewAdapter类,继承BaseAdapter,在该类中定义容器变量mViewList来存储ListView中不同列表项的view;同时,定义两个构造函数,一个是在参数中指定容器的大小,并填充null值;一个则直接传入ListView列表项中所有view的集合。代码如下:
SackOfViewAdapter类的关键代码在newView函数和getView函数,其中newView函数用于给容器变量mViewList中值为null的元素赋值,一般由SackOfViewAdapter的子类实现。而getView函数重写自BaseAdapter类,是Adapter返回View类实例的关键函数,代码如下所示:
SackOfViewAdapter类的完整代码如下所示:
而实例的代码如下:
public class SackOfViewsDemo extends ListActivity { @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); ArrayList<View> views = new ArrayList<View>(); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); // 列表项1 View view = inflater.inflate(R.layout.main_notify, null); views.add(view); // 列表项2 view = inflater.inflate(R.layout.update_progress_notify, null); views.add(view); // 列表项3 view = inflater.inflate(R.layout.notification_battery, null); views.add(view); // 列表项4(为null值,在newView函数中创建) views.add(null); setListAdapter(new SillyAdapter(views)); } class SillyAdapter extends SackOfViewsAdapter { public SillyAdapter(List<View> views) { super(views); } protected View newView(int position, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.main_notify_red, null); return view; } }}本文的SackOfViewAdapter类参考自 https://github.com/commonsguy/cwac-sacklist
本文源码参见:http://download.csdn.net/detail/ace1985/4575749