您的位置:首页 > 产品设计 > UI/UE

setAdapter和requestAsyncTask组合使用揭秘

2016-04-11 23:23 429 查看
在使用setAdapter时我们都是按照listView的优化套路来的如下,在实际应用比较容易出空指针bug,究竟是谁为空了,两个地方,传入的集合和引入的layout布局只有这两个量是外来量,但这里有一个非常有趣的地方,就是它的机制,

机制:

1、整个 MyAdapter 只要你使getCount()返回的值不为空即使是0,这个MyAdapter就不会报错,

2、也就是说如果我们在实现的四个抽象方法 getCount(),getItem(),

getItemId(),getView()中打上log,那么实际上只有getCount(),getView()两个方法执行了,另两个方法只是为了实例化抽象类BaseAdapter而不得不重写才写的,即使是个空实现也不影响结果输出;但是如果你点击条目,getItemId()就会执行并返回点击的position,至于getItem()则提供了返回每一个条目的方法你可以调用它来获取想要的任何一个条目;

3、这个方法的自动更新功能,可以分两种情况来理解:

3.1:正常情况: 当getCount()返回的值不为0:它就会调用BaseAdapter的内部自动更新机制,遍历getCount返回的值,假定返回为4,它就会遍历至少4次,每遍历一次就走一次getView()返回一个条目给控件,并在该方法中封装你需要的数据;

3.2: 当getCount()返回的值为0时,这就是个特殊情况了,如果为0,则该方法到getCount()就结束执行了,jdk会继续执行应用的其他方法;如第二个代码块(转到第二个代码块)

/*设置adapter/

public class MyAdapter extends BaseAdapter {

public MyAdapter(ArrayList dates) {

Dates = dates;

}

//这里将return Dates;返回集合写入方法是为了在另一个类中方便调用

public ArrayList getDatas() {

return Dates;

}

@Override

public int getCount() {

System.out.println(“getCount()方法执行了”);

return Dates==null?0:Dates.size();

}

@Override

public Object getItem(int position) {

System.out.println(“getItem()方法执行了”);

return Dates.get(position);

}

@Override

public long getItemId(int position) {

System.out.println(“getItemId()方法执行了”);

return position;

}

//设置view

@Override

public View getView(final int position, View convertView,ViewGroup parent) {

System.out.println(“getView()方法执行了”);

ViewHolder holder;

if (convertView == null) {

convertView =View.inflate(getApplicationContext(),R.layout.item_view,null);

holder= new ViewHolder();

holder.tv = (TextView) convertView.findViewById(R.id.tv_item);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

holder.tv.setText(Dates.get(position));

return convertView;

}

}

static class ViewHolder {

TextView tv;

}

4、这里是第二个代码块,这段代码的核心有两点:

1、 Dates=new ArrayList();//初始化Datas否则下面的调用不成功

2、 adapter.notifyDataSetChanged();

第一点在注释中已经说明了,我们不能往一个想象出来的杯子里面装水,或者叫画饼充饥,专业点讲就是不能往一个没有初始化的集合里装数据,所以第一步是个核心;

第二点实际上就是在集合中封装了数据后再次更新即再一次调用adapter来适配listView;方法不调用不执行,即使满足了adapter的数据和布局两个条件不调用还是没有意义的。

5、总结: 使用adapter一定要注意是否同时满足集合和布局这两个条件只要满足这两个条件就不会出错这也是这篇文的核心!至于requestAsyncTask就比较简单了,一个异步任务的封装而已,实际是对handler进行了封装,一个在子线程中oInBackground执行获取数据的耗时操作返回return 一个结果result,并定义一个标示requestType,并将result传入onPostExecute方法中在主线程的中更新UI;

/*初始化View/

private void initView() {

listView = (ListView) findViewById(R.id.lv_demo);

/*在adapter中传入null/

adapter = new MyAdapter(null);

listView.setAdapter(adapter);

}

/*初始化数据/

private void initData() {

/*调用异步任务/

requestAsyncTask(TYPE_INIT_DATA);

}

/*设置异步任务/

private void requestAsyncTask(final int requestType) {

new AsyncTask
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: