Android之自定义ListView实现图文混排

1、两个布局文件:

(1)主布局文件activity_main.xml:放置ListView组件即可

(2)列表的item.xml文件(每一行的布局):如一个横向LinearLayout布局文件

 

2、主代码:

public class WillListAdapter extends BaseAdapter {

    private Context mContext;
    private List<Will> mlist = null;
    private LayoutInflater mInflater;
    private WindowManager wm;
    private ImageLoader imageLoader;
  
public WillListAdapter(Context c) { this.mContext = c; mInflater = LayoutInflater.from(mContext); imageLoader = new ImageLoader(VolleyQueue.getInstance(), LruImageCache.getInstance()); wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); } public WillListAdapter(Context c, List<Will> list) { // TODO Auto-generated constructor stub this(c); mlist = list; }/* * 当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。 * 然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。 如果让getCount()返回1,那么只显示一行。 */ @Override public int getCount() { // TODO Auto-generated method stub return mlist.size(); } @Override public Will getItem(int position) { // TODO Auto-generated method stub return mlist.get(position); } public void addItem(Will item) { mlist.add(item); // notifyDataSetChanged()可以在修改适配器绑定的数组后,不用重新刷新Activity,通知Activity更新ListView。 notifyDataSetChanged(); } public void addTopItem(Will item) { mlist.add(0, item); // notifyDataSetChanged()可以在修改适配器绑定的数组后,不用重新刷新Activity,通知Activity更新ListView。 notifyDataSetChanged(); } public void removeItem(int position) { // TODO Auto-generated method stub mlist.remove(position); notifyDataSetChanged(); } public void addItems(List<Will> items) { mlist.addAll(items); notifyDataSetChanged(); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } /* * 当要显示一个View就调用一次这个方法。这个方法是ListView性能好坏的关键。方法中有个convertView, * 这个是Android在为我们而做的缓存机制。 ListView中每个item都是通过getView返回并显示的
*/ @Override public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub final ViewHolder holder; if (convertView == null) { // 这部分只负责根据resourceId取出控件,不负责赋值,赋值需要根据position赋不同值 convertView = mInflater.inflate(R.layout.will_item, null); holder = new ViewHolder(); /** 得到各个控件的对象 */ holder.head = (MaskedImage) convertView.findViewById(R.id.wills_head); // convertView的tag存储的数据不只是控件,包括控件显示的值等状态 // 更准确的说convertView对holder是地址引用,而不是把holder拿过来装在自己里面,当getTag调用时,取的是最新状态的Tag // 即使在setTag和getTag中间这个Tag的内容有发生变化

// 绑定ViewHolder对象 convertView.setTag(holder);// 不因position改变的部分都可以写在这里面 } else { holder = (ViewHolder) convertView.getTag();// 取出ViewHolder对象 } /** 根据不同position显示不同数据 */ final Will will = mlist.get(position); holder.head.setImageUrl(Urls.PREFIX_PIC + will.getPic(), imageLoader);
     
return convertView; } /** * @author Hunter 不是所有控件都要放进来,有些固定的图片或文本不需要改动就不用 */ public final class ViewHolder { public MaskedImage head;
} }

 

(1)注意adapter.notifyDataSetChanged()的使用:

adapter.setData(list);中adapter监听的是list内部内容的变化。

所以list.add添加内容后使用notifyDataSetChanged会有效果

但如果对list=list2这样的重新赋值会让notifyDataSetChanged无效

 (2)holder = (ViewHolder) convertView.getTag();// 取出ViewHolder对象

 的前提是

convertView.setTag(holder);

Done!

posted @ 2013-10-26 15:24  行云有影  阅读(1876)  评论(0)    收藏  举报