【转】Android ListView加载不同的item布局
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有大量的数据需要加载的时候 ...
随机推荐
- 一个简单的基于HTTP协议的屏幕共享应用
HTTP协议可以能是应用层协议里使用最广泛并且用途最多样的一个了.我们一般使用HTTP协议来浏览网页,但是HTTP协议还用来做很多其它用途.对开发人员来讲很常见的一种就是用HTTP协议作为各种版本控制 ...
- setAttribute的兼容性
class和className兼容方法: object.setAttribute("class","content") 在IE8.Chrome.火狐.Opera ...
- Servlet程序开发--Servlet 与 表单
servlet程序: doPost方法时为了防止表单提交时post方式的问题.否则只能处理get请求 package org.lxh.servletdemo ; import java.io.* ; ...
- mysql 远程连接不上 %用户已经添加了
修改mysql的配置文件/etc/mysql/my.conf,将bind-address后面增加远程访问IP地址或者禁掉这句话就可以让远程机登陆访问了. 记得要重启mysql服务哦 service m ...
- CST 公共生成树
本实验只讨论CST(公共的生成树) 一.实验前先理解生成树决策的4 个步骤: 二.实验拓扑 1. 实验描述: 由于业务的要求,要有可靠的链路,要对链路实现冗余,但链路的冗余有可能给网络带来广播风暴,重 ...
- 设置span的宽度
设置span的宽度 在默认的情况下,利用css样式对span进行宽度设定是无效,但有时为了某种排版的要求,需要对span进行宽度设定,那么如何在html中利用css样式设定span的宽度? 思路:这看 ...
- Spring+Struts集成(方案一)
SSH框架是现在非常流行的框架之一,本文接下来主要来对Spring和Struts的集成进行展示. 集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象. 集 ...
- Android Fragment 真正的完全解析(上)--转
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37970961 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fra ...
- JavaFX 2.0+ WebView /WebEngine render web page to an image
http://stackoverflow.com/questions/7796558/javafx-2-0-webview-webengine-render-web-page-to-an-image ...
- springmvc配置首页的方式
<mvc:view-controller path="/" view-name="redirect:/user/loginUI" />