博主学安卓学了一个多月,现在暑期在学校接受培训,闲时写一点自己查阅了资料,有感悟的一些知识和心得,在人生规划里,未来我不想做一名程序员,只是现在我会好好学,博主知识水平有限,有些没写对的地方,还请点评指出,我也写不出太多太深的东西,更多的我会贴出一些自己找到觉得有用的链接。
首先,ListView和Adapter的关系,就是ListView是针对List中每个item,用getView方法要求 adapter 给一个视图。
Adapter又可以分为ArraryAdapter、SimpleAdapter和BaseAdapter。
ArraryAdapter:只能显示一行文字
SimpleAdapter:可以显示比较复杂的列表,包括每行显示图片、文字等,但不能对列表进行后期加工
三类适配器非常详细的代码可参考:适配器的区别
BaseAdapter:可以实现复杂的列表布局,但BaseAdapter是一个抽象类,使用该类需要自己写一个适配器继承该类,方法有getCount( )、getItem( )、getItemId( )、getView( )。
我们可以看看下面这段代码:
<span style="white-space:pre"> </span>public class MyAdapter extends BaseAdapter {
<span style="white-space:pre"> </span>private LayoutInflater mInflater;
<span style="white-space:pre"> </span>public MyAdapter(Context context) {
<span style="white-space:pre"> </span>this.mInflater = LayoutInflater.from(context);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public int getCount() {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>return mData.size();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public Object getItem(int position) {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>return null;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public long getItemId(int position) {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>return 0;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public View getView(final int position, View convertView, ViewGroup parent) {
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
其中,上面的LayoutInflater的作用类似于findViewById(),不同是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。
对此觉得想深入了解的朋友可以参考网页:LayoutInflater详解
上面继承后的方法,getItem 和 getItemId 根据名字都好理解,getCount的作用则是返回List的个数,而getView 包含三个参数,即getView(int position, View convertView, ViewGroup parent),其中,position就是你选中item的位置,convertView就是item上的布局layout或者组件,parent 就是设置的adapter那个组件里面封装一个viewGroup用来盛放item的(也可理解为List)。
在很多代码中,我们常常会看到 getView 这个方法里面有一个ViewHolder在创建对象,这个ViewHolder并不是自带的,而是自己编写的一个类,在类中集中创建对象,可以用来减少每次都重新创建对象的烦琐。
对此觉得想深入了解的朋友可以参考两个网页:ViewHolder详解01ViewHolder详解02
使用ViewHolder和不使用ViewHolder的区别:
<span style="font-family:Microsoft YaHei;font-size:14px;">private class MyListAdapter extends BaseAdapter{
private Context mContext;
private int[] colors=new int[]{0xff626569,0xff4f5257 };
public MyListAdapter(Context context){
mContext=context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mListText.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView image=null; //这些控件可以单独封装成一个类(Holder),便与优化
TextView title=null;
TextView content=null;
if(convertView==null){
convertView=LayoutInflater.from(mContext).inflate(R.layout.colorlist, null);
image=(ImageView) convertView.findViewById(R.id.color_image);
title=(TextView) convertView.findViewById(R.id.color_title);
content=(TextView) convertView.findViewById(R.id.color_text);
}
int colorPos=position%colors.length;
convertView.setBackgroundColor(colors[colorPos]);
title.setText(mListTitle[position]);
content.setText(mListText[position]);
image.setImageResource(R.drawable.portrait);
return convertView;
}
}
--------------------------下面样例列表页的控件单独封装成了一个类(Holder),便与优化-----
public class MyBaseAdapter extends BaseAdapter{
private LayoutInflater mInflater;
public MyAdapter(Context context){
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder=new ViewHolder();
convertView = mInflater.inflate(R.layout.vlist2, null);
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.title = (TextView)convertView.findViewById(R.id.title);
holder.info = (TextView)convertView.findViewById(R.id.info);
holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
holder.title.setText((String)mData.get(position).get("title"));
holder.info.setText((String)mData.get(position).get("info"));
//给每一个列表后面的按钮添加响应事件
holder.viewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showInfo();
}
});
return convertView;
}
------------
public final class ViewHolder{
public ImageView img;
public TextView title;
public TextView info;
public Button viewBtn;
}</span>
这里有一个实例可以详细感受到 getView 中参数的作用:getView原理实例
附加两个ListView和BaseAdapter、ListView和SimpleAdapter的实例项目文件:
ListView和SimpleAdapter简单搭配 ListView和BaseAdapter搭配Button点击事件获取不同Item