public View getView(int position, View convertView, ViewGroup parent) {
View view = new Xxx(...);
... ...
return view;
}
以构造ListView的BaseAdapter为例,在BaseAdapter中提供了方法:
public View getView(int position, View convertView, ViewGroup parent){ }
由此可以看出,如果我们不去使用convertView,而是每次都在getView()中重新实例化一个View对象的话,即浪费资源也浪费时间,也会使得内存占用越来越大。
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
...
} else {
view = new Xxx(...);
...
}
return view;
}
但是如果出现如下图的需求,convertView就不太好用了,convertView在Item为单一的布局时,能够回收并重用,但是多个Item布局时,convertView的回收和重用会出现问题。
官网解释如下,不解释了
Get the type of View that will be created by getView(int, android.view.View, android.view.ViewGroup)]getView(int, View, ViewGroup) for the specified item.
Parameters
position | The position of the item within the adapter's data set whose view type we want. |
Returns
- An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, android.view.View, android.view.ViewGroup)getView(int, View, ViewGroup). Note: Integers must be in the range 0 to getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPE can also be returned.
Get the type of View that will be created by getView(int, android.view.View, android.view.ViewGroup)getView(int, View, ViewGroup) for the specified item.
Parameters
position | The position of the item within the adapter's data set whose view type we want. |
Returns
- An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, android.view.View, android.view.ViewGroup)getView(int, View, ViewGroup). Note: Integers must be in the range 0 to getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPE can also be returned.
- package com.bestv.listViewTest;
- import java.util.ArrayList;
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.CheckBox;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.TextView;
- public class listViewTest extends Activity {
- /** Called when the activity is first created. */
- ListView listView;
- MyAdapter listAdapter;
- ArrayList<String> listString;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- listView = (ListView)this.findViewById(R.id.listview);
- listString = new ArrayList<String>();
- for(int i = 0 ; i < 100 ; i++)
- {
- listString.add(Integer.toString(i));
- }
- listAdapter = new MyAdapter(this);
- listView.setAdapter(listAdapter);
- }
- class MyAdapter extends BaseAdapter{
- Context mContext;
- LinearLayout linearLayout = null;
- LayoutInflater inflater;
- TextView tex;
- final int VIEW_TYPE = 3;
- final int TYPE_1 = 0;
- final int TYPE_2 = 1;
- final int TYPE_3 = 2;
- public MyAdapter(Context context) {
- // TODO Auto-generated constructor stub
- mContext = context;
- inflater = LayoutInflater.from(mContext);
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return listString.size();
- }
- //每个convert view都会调用此方法,获得当前所需要的view样式
- @Override
- public int getItemViewType(int position) {
- // TODO Auto-generated method stub
- int p = position%6;
- if(p == 0)
- return TYPE_1;
- else if(p < 3)
- return TYPE_2;
- else if(p < 6)
- return TYPE_3;
- else
- return TYPE_1;
- }
- @Override
- public int getViewTypeCount() {
- // TODO Auto-generated method stub
- return 3;
- }
- @Override
- public Object getItem(int arg0) {
- // TODO Auto-generated method stub
- return listString.get(arg0);
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- viewHolder1 holder1 = null;
- viewHolder2 holder2 = null;
- viewHolder3 holder3 = null;
- int type = getItemViewType(position);
- //无convertView,需要new出各个控件
- if(convertView == null)
- {
- Log.e("convertView = ", " NULL");
- //按当前所需的样式,确定new的布局
- switch(type)
- {
- case TYPE_1:
- convertView = inflater.inflate(R.layout.listitem1, parent, false);
- holder1 = new viewHolder1();
- holder1.textView = (TextView)convertView.findViewById(R.id.textview1);
- holder1.checkBox = (CheckBox)convertView.findViewById(R.id.checkbox);
- Log.e("convertView = ", "NULL TYPE_1");
- convertView.setTag(holder1);
- break;
- case TYPE_2:
- convertView = inflater.inflate(R.layout.listitem2, parent, false);
- holder2 = new viewHolder2();
- holder2.textView = (TextView)convertView.findViewById(R.id.textview2);
- Log.e("convertView = ", "NULL TYPE_2");
- convertView.setTag(holder2);
- break;
- case TYPE_3:
- convertView = inflater.inflate(R.layout.listitem3, parent, false);
- holder3 = new viewHolder3();
- holder3.textView = (TextView)convertView.findViewById(R.id.textview3);
- holder3.imageView = (ImageView)convertView.findViewById(R.id.imageview);
- Log.e("convertView = ", "NULL TYPE_3");
- convertView.setTag(holder3);
- break;
- }
- }
- else
- {
- //有convertView,按样式,取得不用的布局
- switch(type)
- {
- case TYPE_1:
- holder1 = (viewHolder1) convertView.getTag();
- Log.e("convertView !!!!!!= ", "NULL TYPE_1");
- break;
- case TYPE_2:
- holder2 = (viewHolder2) convertView.getTag();
- Log.e("convertView !!!!!!= ", "NULL TYPE_2");
- break;
- case TYPE_3:
- holder3 = (viewHolder3) convertView.getTag();
- Log.e("convertView !!!!!!= ", "NULL TYPE_3");
- break;
- }
- }
- //设置资源
- switch(type)
- {
- case TYPE_1:
- holder1.textView.setText(Integer.toString(position));
- holder1.checkBox.setChecked(true);
- break;
- case TYPE_2:
- holder2.textView.setText(Integer.toString(position));
- break;
- case TYPE_3:
- holder3.textView.setText(Integer.toString(position));
- holder3.imageView.setBackgroundResource(R.drawable.icon);
- break;
- }
- return convertView;
- }
- }
- //各个布局的控件资源
- class viewHolder1{
- CheckBox checkBox;
- TextView textView;
- }
- class viewHolder2{
- TextView textView;
- }
- class viewHolder3{
- ImageView imageView;
- TextView textView;
- }
- }
复制代码
在getView()中需要将不同布局进行缓存和适配,系统在判断是否有convertView时,会自动去调用getItemViewType (int position) ,查看是否已经有缓存的该类型的布局,从而进入if(convertView == null)和else{}的判断。期间需要做的是convertView.setTag(holder3),以便在convertView重用时可以直接拿到该布局的控件,holder3 = (viewHolder3) convertView.getTag()。到这一步,convertView的回收和重用就已经写好了,接下来只需要对你的不同的控件进行设置就行了。
还有一种方法:
在主布局文件中包含一个LinearLayout. 并且设置android:orientation="vertical"
定义两种不同的布局文件,然后代码中,根据不同条件调用.addview向LinearLayout加载就可以了
在实践中遇到的问题:
发现在加载的时候,会出现classcastexception,不同的viewholder在转换的时候会出现这个问题,后来找了原因,有这样解释的:http://www.eoeandroid.com/thread-263957-1-1.html
所以就捕捉这个异常,
if(convertView == null){//无convertView,需要new出各个控件 //按当前所需的样式,确定new的布局
switch (type) {
case ARTICLE :
discussesInflater = LayoutInflater.from(discussescontext);
convertView = discussesInflater.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:
discussesInflater = LayoutInflater.from(discussescontext);
convertView = discussesInflater.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;
}
}else {//有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;
}
}
【转】Android ListView加载不同的item布局的更多相关文章
-
android ListView加载不同布局
今天来跟大家讨论下同一个ListView如何加载不同的布局. 老规矩,先来看效果图. 主要步骤如下 1.增加Type. 2.重写getViewTypeCount方法. 3.重写getItemViewT ...
-
Android ListView加载更多
先看效果: ListView的footer布局: <?xml version="1.0" encoding="utf-8"?> <Relati ...
-
android listview 加载图片错乱(错位)
写道 今天晚上一个朋友介绍我看了一篇文章,也是解决android中listview在加载图片错位的问题,看了之后,感觉写的很好,自己也遇到这个问题,但是又不知道从何下手,看到这篇文章后,我的问题 ...
-
android listview 加载遇到的问题
http://blog.csdn.net/l_serein/article/details/7706338 转载: 描述一下场景: 菜单栏上有若干分类,点击每一个分类,ListView下分根据分类显示 ...
-
android之 listview加载性能优化ViewHolder
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以*的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...
-
[Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html 这个可以实现ImageView异步加载 ...
-
Android图片加载与缓存开源框架:Android Glide
<Android图片加载与缓存开源框架:Android Glide> Android Glide是一个开源的图片加载和缓存处理的第三方框架.和Android的Picasso库类似,个人感觉 ...
-
一起写一个Android图片加载框架
本文会从内部原理到具体实现来详细介绍如何开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做 ...
-
listview加载性能优化ViewHolder
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以*的定义listview每一列的布局, 但当listview有大量的数据需要加载的时候 ...
随机推荐
-
Atitit &#160;如何让精灵控件运动
Atitit 如何让精灵控件运动 ##让Sushi精灵动起来 上面的代码,我们创建了静态的sushiSprite,现在我们让它动起来.使它从屏幕顶部下落到屏幕底部.在addSushi方法中添加如下代 ...
-
地理围栏算法解析(Geo-fencing)
地理围栏算法解析 http://www.cnblogs.com/LBSer/p/4471742.html 地理围栏(Geo-fencing)是LBS的一种应用,就是用一个虚拟的栅栏围出一个虚拟地理边界 ...
-
Effective Java 11 Override clone judiciously
Principles If you override the clone method in a nonfinal class, you should return an object obtaine ...
-
html元素英文含义
常用html标签的英语全称及简单功能描述 <a>:anchor 定义锚 <abbr>:abbreviation 定义缩写 <acronym>: 定义只取消首字母的缩 ...
-
js中substring和substr的用法 (转)
1.substring 方法 定义和用法 substring 方法用于提取字符串中介于两个指定下标之间的字符. 语法 stringObject.substring(start,stop) 参数 ...
-
Decision Trees:机器学习根据大量数据,已知年龄、收入、是否上海人、私家车价格的人,预测Ta是否有真实购买上海黄浦区楼房的能力—Jason niu
from sklearn.feature_extraction import DictVectorizer import csv from sklearn import tree from sklea ...
-
windows版 Java调用人脸识别离线sdk
最近因工作需求在java-web服务中调用人脸识别离线sdk,主要通过JNA及JNI技术,但均未调试通过,JNA调用时出现以下异常,一直未解决,求大佬指点,导常信息如下: in BaiduFaceAp ...
-
【Oracle】浅析Oracle中的事务
1. 什么是事务 在数据库中事务是工作的逻辑单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个工作单元操作,要么一个也不 ...
-
Linux系统中切换用户身份su与sudo的用法与实例
日常操作中为了避免一些误操作,更加安全地管理系统,通常使用的用户身份都为普通用户,而非root.当需要执行一些管理员命令操作时,再切换成root用户身份去执行. 普通用户切换到root用户的方式有:s ...
-
cvc-complex-type.2.4.a: Invalid content was found starting with element ‘init-param’(转)
在写xml的时候又一次总是报cvc-complex-type.2.4.a: Invalid content was found starting with element 错误,还出现小红叉,在网上找 ...