对于有其他语言基础的android入门者来说,android中的listview有些特别。因为对listview的数据操作,是通过适配器来操作的。
如果你原来是C#的,对这种操作方式会不习惯。这里记录下怎么按我们线性的步骤来实现listview的数据操作。
想要使用listview,我们要做的准备有哪些?
创建一个listview对象、准备好要加载到listview中的数据、以及相对特殊的适配器;
首先,我们定义好需要的参数,如下:
ListView listView; //listview对象
List<String> newList=null; //数据对象
BaseAdapter baseAdapter; //适配器对象
其次,我们要实例化这些对象。
listview,我们可以通过findviewbyid获取到实例;
newList,这里我们可以手动赋值,做为测试数据;
baseAdapter,这个就是适配器对象,这是比较特别的地方,在后面会详细讲到;
listView=(ListView)findViewById(R.id.titles);
newList=new ArrayList<String>();
newList.add("标题四");
newList.add("标题五");
newList.add("标题六");
然后,我们怎么把数据装载到ListView控件中?
android中是这么做的,把数据装载到适配器中,然后将适配器与ListView控件绑定。
那么,我们这会要做的就是把数据装到适配器中。
我们需要实例化,我们定义的适配器baseAdapter,先定义一个适配器继承类,如下:
class BaseOne extends BaseAdapter
{
Context context;
int resourceid;
List<String> data;
public BaseOne(Context context,int resourceid,List<String> data)
{
this.context=context;
this.resourceid=resourceid;
this.data=data;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
@Override
public Object getItem(int paramInt) {
// TODO Auto-generated method stub
return data.get(paramInt);
}
@Override
public long getItemId(int paramInt) {
// TODO Auto-generated method stub
return paramInt;
}
@Override
public View getView(int paramInt, View paramView, ViewGroup paramViewGroup) {
// TODO Auto-generated method stub
ViewHolder viewHolder;
if(paramView==null)
{
viewHolder=new ViewHolder();
paramView=LayoutInflater.from(context).inflate(resourceid, paramViewGroup,false);
viewHolder.tView=(TextView)paramView.findViewById(R.id.txt);
paramView.setTag(viewHolder);
}
else
{
viewHolder=(ViewHolder)paramView.getTag();
}
viewHolder.tView.setText(getItem(paramInt)+"");
return paramView;
}
}
class ViewHolder
{
TextView tView;
}
baseAdapter的实例,就可以通过我们这个自定义的类来得到,如:
baseAdapter=new BaseOne(MainActivity.this, R.layout.list_title, newList);
现在我们得到了baseAdapter的实例了,下一步就是把实例绑定到listview控件上,如下:
listView.setAdapter(baseAdapter);
baseAdapter.notifyDataSetChanged();
这里,我们绑定了适配器,并通知listview。
总结一下我们使用listview的过程,其实就是定义listview、准备数据、加载数据三部,如下:
listView=(ListView)findViewById(R.id.titles);
newList=new ArrayList<String>();
newList.add("标题四");
newList.add("标题五");
newList.add("标题六");
baseAdapter=new BaseOne(MainActivity.this, R.layout.list_title, newList);
listView.setAdapter(baseAdapter);
baseAdapter.notifyDataSetChanged();
O了。上面已经是完成一个listview的简单流程了。现在我们仔细分析一下适配器。
以上面写的BaseOne为例,它继承系统提供的BaseAdapter,有默认方法带出。我往其中增加了一个构造函数,主要是为了传输数据,构造函数如下:
public BaseOne(Context context,int resourceid,List<String> data)
{
this.context=context; //这个是用于传上下文说明,你在哪个界面,就传哪个界面的context。如MainActivity.this
this.resourceid=resourceid; //这个是你要加载哪个布局<span style="font-family: Arial, Helvetica, sans-serif;">在context界面上,如R.layout.xx</span>
this.data=data; //这个就是你要显示的数据了
}
还有这些,都是继承BaseAdapter的时候,带出来的默认重载函数,可以按下面写法返回;
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size(); //数据的长度
}
@Override
public Object getItem(int paramInt) {
// TODO Auto-generated method stub
return data.get(paramInt);//数据内容
}
@Override
public long getItemId(int paramInt) {
// TODO Auto-generated method stub
return paramInt; //索引,数据的位置
}
重点是,getView这个重载函数,它做的就是将数据一行行的加载到适配器中。
getView的调用次数等于getCount()的返回值。如果将getCount()的返回值设为0,则不调用getView。
getView的意义就是把data中的每一条数据,都显示在listview上。它真正的意思可以用以下代码表示出来(把数据显示在listview中的textview上):
public View getView(int paramInt, View paramView, ViewGroup paramViewGroup) {
// TODO Auto-generated method stub
textView.setText(getItem(paramInt)+"");
return paramView;
}
但以上的代码是会出错的,因为你找不到TextView。要找到TextView,需要找到所在的容器。这里就用到我们传入的参数context以及resourceid了。
代码如下:
其中的ViewHolder是定义在listview控件中要显示的是什么,有几列等。如果要新增显示内容,可以在ViewHolder中添加。
setTag(xx)与getTag():View中的setTag(xx)表示给View添加一个格外的数据,以后可以用getTag()将这个数据取出来。
主要作用是得到控件的对象,避免null。
而inflate的三个参数,可以参考:http://blog.csdn.net/lmj623565791/article/details/38171465 ,这个博客中写的很详细。
@Override
public View getView(int paramInt, View paramView, ViewGroup paramViewGroup) {
// TODO Auto-generated method stub
ViewHolder viewHolder;
if(paramView==null)
{
viewHolder=new ViewHolder();
paramView=LayoutInflater.from(context).inflate(resourceid, paramViewGroup,false);
viewHolder.tView=(TextView)paramView.findViewById(R.id.txt);
paramView.setTag(viewHolder);
}
else
{
viewHolder=(ViewHolder)paramView.getTag();
}
viewHolder.tView.setText(getItem(paramInt)+"");
return paramView;
}
class ViewHolder
{
<span style="white-space: pre;"> </span>TextView tView;
}