Android ListView加载不同的item

实现代码

Adapter的代码

其中:ViewHolder分别是三个不同的布局,也就是ListView中每一项的布局

TYPE_1...是三种类型.

在使用不同布局的时候,getItemViewType和getViewType不能少,一般是不用这两个函数的重载的

[java]  view plain copy
  1. class RunRankAdapter extends BaseAdapter {  
  2.     ArrayList<HashMap<String, Object>> ls;  
  3.     Context mContext;  
  4.     LinearLayout linearLayout = null;  
  5.     LayoutInflater inflater;  
  6.     TextView tex;  
  7.     final int VIEW_TYPE = 3;  
  8.     final int TYPE_1 = 0;  
  9.     final int TYPE_2 = 1;  
  10.     final int TYPE_3 = 2;  
  11.   
  12.     public RunRankAdapter(Context context,  
  13.             ArrayList<HashMap<String, Object>> list) {  
  14.         ls = list;  
  15.         mContext = context;  
  16.     }  
  17.   
  18.     @Override  
  19.     public int getCount() {  
  20.         return ls.size();  
  21.     }  
  22.   
  23.     @Override  
  24.     public Object getItem(int position) {  
  25.         return ls.get(position);  
  26.     }  
  27.   
  28.     @Override  
  29.     public long getItemId(int position) {  
  30.         return 0;  
  31.     }  
  32.   
  33.     // 每个convert view都会调用此方法,获得当前所需要的view样式  
  34.     @Override  
  35.     public int getItemViewType(int position) {  
  36.         int p = position;  
  37.         if (p == 0)  
  38.             return TYPE_1;  
  39.         else if (p == 1)  
  40.             return TYPE_2;  
  41.         else  
  42.             return TYPE_3;  
  43.     }  
  44.   
  45.     @Override  
  46.     public int getViewTypeCount() {  
  47.         return 3;  
  48.     }  
  49.   
  50.     @Override  
  51.     public View getView(int position, View convertView, ViewGroup parent) {  
  52.         ViewHolder1 holder1 = null;  
  53.         ViewHolder2 holder2 = null;  
  54.         ViewHolder3 holder3 = null;  
  55.         int type = getItemViewType(position);  
  56.         if (convertView == null) {  
  57.             inflater = LayoutInflater.from(mContext);  
  58.             // 按当前所需的样式,确定new的布局  
  59.             switch (type) {  
  60.             case TYPE_1:  
  61.   
  62.                 convertView = inflater.inflate(R.layout.item_runrank1,  
  63.                         parent, false);  
  64.                 holder1 = new ViewHolder1();  
  65.                 holder1.rank1 = (TextView) convertView  
  66.                         .findViewById(R.id.tv_list1_rank);  
  67.                 holder1.time1 = (TextView) convertView  
  68.                         .findViewById(R.id.tv_list1_time);  
  69.                 convertView.setTag(holder1);  
  70.                 break;  
  71.             case TYPE_2:  
  72.                 convertView = inflater.inflate(R.layout.item_runrank2,  
  73.                         parent, false);  
  74.                 holder2 = new ViewHolder2();  
  75.                 holder2.rank2 = (TextView) convertView  
  76.                         .findViewById(R.id.tv_list2_rank);  
  77.                 holder2.time2 = (TextView) convertView  
  78.                         .findViewById(R.id.tv_list2_time);  
  79.                 convertView.setTag(holder2);  
  80.                 break;  
  81.             case TYPE_3:  
  82.                 convertView = inflater.inflate(R.layout.item_runrank3,  
  83.                         parent, false);  
  84.                 holder3 = new ViewHolder3();  
  85.                 holder3.rank3 = (TextView) convertView  
  86.                         .findViewById(R.id.tv_list3_rank);  
  87.                 holder3.time3 = (TextView) convertView  
  88.                         .findViewById(R.id.tv_list3_time);  
  89.                 convertView.setTag(holder3);  
  90.                 break;  
  91.             default:  
  92.                 break;  
  93.             }  
  94.   
  95.         } else {  
  96.             switch (type) {  
  97.             case TYPE_1:  
  98.                 holder1 = (ViewHolder1) convertView.getTag();  
  99.                 break;  
  100.             case TYPE_2:  
  101.                 holder2 = (ViewHolder2) convertView.getTag();  
  102.                 break;  
  103.             case TYPE_3:  
  104.                 holder3 = (ViewHolder3) convertView.getTag();  
  105.                 break;  
  106.             }  
  107.         }  
  108.         // 设置资源  
  109.         switch (type) {  
  110.         case TYPE_1:  
  111.             holder1.rank1.setText("" + (position + 1));  
  112.             holder1.time1.setText(ls.get(position).get("time").toString());  
  113.             break;  
  114.         case TYPE_2:  
  115.             holder2.rank2.setText("" + (position + 1));  
  116.             holder2.time2.setText(ls.get(position).get("time").toString());  
  117.             holder2.totaldistance2.setText(ls.get(position)  
  118.             break;  
  119.         case TYPE_3:  
  120.             holder3.rank3.setText("" + (position + 1));  
  121.             holder3.time3.setText(ls.get(position).get("time").toString());  
  122.             break;  
  123.         }  
  124.   
  125.         return convertView;  
  126.     }  
  127.   
  128.     public class ViewHolder1 {  
  129.         TextView rank1;  
  130.         TextView time1;  
  131.     }  
  132.   
  133.     public class ViewHolder2 {  
  134.         TextView rank2;  
  135.         TextView time2;  
  136.     }  
  137.   
  138.     public class ViewHolder3 {  
  139.         TextView rank3;  
  140.         TextView time3;  
  141.     }  
  142. }  

使用方式:

声明并定义自己的Adapter,在ListView中设置他的Adapter

[java]  view plain copy
  1. private RunRankAdapter runRankAdapter;    
  2. ArrayList<HashMap<String, Object>> runRank;    
  3. ListView lv_runRank;  
  4. runRank = new ArrayList<HashMap<String, Object>>();    
  5. runRankAdapter = new RunRankAdapter(this, runRank);    
  6. lv_runRank = (ListView) findViewById(R.id.lv_runRank);    
  7. lv_runRank.setAdapter(runRankAdapter);  


还有一种方法:

在主布局文件中包含一个LinearLayout. 并且设置android:orientation="vertical"
定义两种不同的布局文件,然后代码中,根据不同条件调用.addview向LinearLayout加载就可以了

在实践中出现的问题:

发现在加载的时候,会出现classcastexception,在网上找到的回答是listview复用出现的问题,http://www.eoeandroid.com/thread-263957-1-1.html

因为在ListView中的convertView会被重用,所以当你根据type去强转convertView.getTag()的时候,你并不知道此时convertView.getTag()返回的是哪一个holder,所以强转自然会出错。对于listView是如何实现复用的,你可以去网上看看,有好例子。
关于你这个问题,我举个例子。
比如你一屏显示了10条记录,显示的holder类型顺序是0,1,2,3,0,1,2,3,0,1,当要显示第11跳记录的时候,因为没有可服用的,此时会重新创建convertView,所以第11个是convertView是null,此时不会出错,当显示第12个的时候,因为第1个(holder0)看不见了,此时系统会去复用它,则当要创建第12个getView时,传入的convertView!=null,即用的是holder0的convertView,但是现在要显示的类型是3,则在convertView.getTag()的时候,就出现错误了。

//有convertView,按样式,取得不用的布局
        	switch (type) {
     		case ARTICLE :
     			try {
					holder1 = (ViewHolder1) convertView.getTag();
					if (holder1 == null) {
						holder1 = new ViewHolder1();
						convertView = LayoutInflater.from(discussescontext).inflate(R.layout.my_favourate_detail_item, null); 
						holder1.wvFavouriteDetails = (WebView)convertView.findViewById(R.id.wv_my_favourite_details);  
			        	holder1.tv_subject_my_favourite_details = (TextView)convertView.findViewById(R.id.tv_subject_my_favourite_details);  
			        	holder1.tv_more_my_favourite_details1= (TextView)convertView.findViewById(R.id.tv_more_my_favourite_details1);  
			        	holder1.tv_more_my_favourite_details2= (TextView)convertView.findViewById(R.id.tv_more_my_favourite_details2); 
			        	convertView.setTag(holder1);
					}
				} catch (Exception e) {
					holder1 = new ViewHolder1();
					convertView = LayoutInflater.from(discussescontext).inflate(R.layout.my_favourate_detail_item, null);
					holder1.wvFavouriteDetails = (WebView)convertView.findViewById(R.id.wv_my_favourite_details);  
		        	holder1.tv_subject_my_favourite_details = (TextView)convertView.findViewById(R.id.tv_subject_my_favourite_details);  
		        	holder1.tv_more_my_favourite_details1= (TextView)convertView.findViewById(R.id.tv_more_my_favourite_details1);  
		        	holder1.tv_more_my_favourite_details2= (TextView)convertView.findViewById(R.id.tv_more_my_favourite_details2); 
		        	convertView.setTag(holder1);
				}
     			break;
     		case COMMENT:
     			try {
        			holder2 = (ViewHolder2) convertView.getTag();
					if (holder2 == null) {
						holder2 = new ViewHolder2();
						convertView = LayoutInflater.from(discussescontext).inflate(R.layout.discussespic_item, null);
						holder2.discussespic = (ImageView) convertView.findViewById(R.id.iv_discussespic);  
		                holder2.discussestext = (TextView) convertView.findViewById(R.id.tv_discussestext);  
		                holder2.nametext = (TextView) convertView.findViewById(R.id.tv_nametext); 
		                holder2.discussespic = (com.haojiazhang.widget.CircularImage)convertView.findViewById(R.id.iv_discussespic);
		                convertView.setTag(holder2);  
					}
				} catch (Exception e) {
					holder2 = new ViewHolder2();
					convertView = LayoutInflater.from(discussescontext).inflate(R.layout.discussespic_item, null);
					holder2.discussespic = (ImageView) convertView.findViewById(R.id.iv_discussespic);  
	                holder2.discussestext = (TextView) convertView.findViewById(R.id.tv_discussestext);  
	                holder2.nametext = (TextView) convertView.findViewById(R.id.tv_nametext); 
	                holder2.discussespic = (com.haojiazhang.widget.CircularImage)convertView.findViewById(R.id.iv_discussespic);
	                convertView.setTag(holder2);  
				}
     			break;
     		default:
     			break;
     		}
        }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值