Android开源代码解读-基于SackOfViewAdapter类实现类似状态通知栏的布局
2012-09-17 16:42
337 查看
一般来说,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类的完整代码如下所示:
最后,以一个实例来说明SackOfViewAdapter类的使用方法,实例中我们定义4个不同布局的列表项,其中一个为null值,由SackOfViewAdapter的子类重写newView函数实现赋值,其他三个则不是null值。这四个view的布局文件分别是main_notify.xml、update_progress_notify.xml、notification_battery.xml和main_notify_red.xml,这些资源借用自360手机卫士,实例效果如下图所示:
而实例的代码如下:
本文的SackOfViewAdapter类参考自 https://github.com/commonsguy/cwac-sacklist
本文源码参见:http://download.csdn.net/detail/ace1985/4575749
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 SackOfViewsAdapter extends BaseAdapter { private List<View> mViewList = null; /** * 构造大小为count,值为null的view集合,这时需要子类重写newView函数 */ public SackOfViewsAdapter(int count) { super(); mViewList = new ArrayList<View>(count); for (int i = 0; i < count; i++) { mViewList.add(null); } } /** * 由传入的view集合直接给容器赋值,如果view集合中有为null值的view,则子类必须实现newView函数 */ public SackOfViewsAdapter(List<View> views) { super(); this.mViewList = views; } /** * 返回对应位置的列表项 */ @Override public Object getItem(int position) { return mViewList.get(position); } /** * 返回列表项的个数 */ @Override public int getCount() { return mViewList.size(); } /** * getView函数创建的列表项类型个数 */ @Override public int getViewTypeCount() { return getCount(); } /** * getView函数创建的view类型值,这里以view所在的位置作为类型值 */ @Override public int getItemViewType(int position) { return position; } /** * 如果Adapter中所有列表项都是可点击和可选择的,则返回true */ @Override public boolean areAllItemsEnabled() { return false; } /** * 如果position所指的列表项不是分隔符,则返回true */ @Override public boolean isEnabled(int position) { return false; } /** * 返回指定位置position的列表项的view */ @Override public View getView(int position, View convertView, ViewGroup parent) { View result = mViewList.get(position); // 如果mViewList中的view为null,则需要调用newView函数来创建一个,该函数由子类来实现 if (result == null) { result = newView(position, parent); mViewList.set(position, result); } return result; } /** * 创建列表中指定位置的列表项,该函数有子类实现 */ protected View newView(int position, ViewGroup parent) { throw new RuntimeException("You must override newView()!"); } /** * 获得指定位置的列表项的id */ @Override public long getItemId(int position) { return position; } /** * 判断Adapter中是否存在某个指定的view */ public boolean hasView(View v) { return mViewList.contains(v); } }
最后,以一个实例来说明SackOfViewAdapter类的使用方法,实例中我们定义4个不同布局的列表项,其中一个为null值,由SackOfViewAdapter的子类重写newView函数实现赋值,其他三个则不是null值。这四个view的布局文件分别是main_notify.xml、update_progress_notify.xml、notification_battery.xml和main_notify_red.xml,这些资源借用自360手机卫士,实例效果如下图所示:
而实例的代码如下:
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
相关文章推荐
- Android开源代码解读-基于SackOfViewAdapter类实现类似状态通知栏的布局
- Android监听手机电话状态与发送邮件通知来电号码的方法(基于PhoneStateListene实现)
- Android 一个例子来解读Fragment实现横竖屏不同的布局
- Android开源代码解读の地图照片应用Panoramio的实现详解(一)
- Android 布局手势缩放,可滑动查看,实现类似Imgview图片缩放效果
- html中类似qq状态的布局,评论+初学者实现方式
- Android开源代码解读の地图照片应用Panoramio的实现详解(一)
- Android基于ViewPager实现类似微信页面切换效果
- 【android开发】实现Activity息屏状态下点亮屏幕并弹出(类似来电界面)
- 【Android】使用Notification实现状态通知栏的通知
- Android 一个例子来解读Fragment实现横竖屏不同的布局
- Android开源代码解读のOnScrollListener实现ListActivity滚屏首字母提示
- Android不使用自定义布局情况下实现自定义通知栏图标的方法
- Android实现类似qq微信消息悬浮窗通知功能
- Android中RecyclerView布局代替GridView实现类似支付宝的界面
- Android开源代码解读のOnScrollListener实现ListActivity滚屏首字母提示
- Unity干中学——如何实现类似Windows Store 应用程序和Android Toast的通知?
- 基于Android代码实现常用布局
- Android开源代码解读の地图照片应用Panoramio的实现详解(四)
- 仿微信、短信、QQ等消息数目右上角红色小圆球气泡显示(基于Android XML布局文件实现)