ListView学习之优化

(1).重写适配器的getView方法时,getView方法有三个参数

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

<span style="white-space:pre">	</span>有了这个参数,我们不必每调用一次getView,就重新加载一次布局,

其中第二个参数convertView用于将之前加载好的布局进行缓存。getView()方法列表子项滚动到屏幕内就会调用一次,用户频繁滑动就会频繁的调用getView,所以里面最好不要有很耗时的操作,比如每调用一次getView方法就重新加载一次布局,当用户频繁的滑动列表时,频繁的调用getView(),然后频繁的重新加载布局.....

我们可以用第二个参数,判断一下是否有缓存,有的话直接重用,没有就用inflate方法动态加载布局。

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

View mView;

if(convertView==null){//没有缓存

mView=LayoutInflater.from(this).inflate(R.layout.list_item,null);

}

else{//有缓存,重用,不用inflate加载了

mView=convertView;

}

TextView textView=(TextView) mView.findViewById(R.id.text_view);

textView.setText("...");

return mView;

}



(2).在(1)的代码中,如果用户频繁滑动列表,getView()方法频繁调用,那么上述代码中TextView textView=(TextView) mView.findViewById(R.id.text_view)会在随着getView()方法的调用,一次一次的获取控件的实例。

public class xxAdapter extends ArrayAdapter<xx>{

.......

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

View mView;

ViewHolder viewHolder;

if(convertView==null){

mView=LayoutInflater.from(this).inflate(R.layout.list_item,null);

viewHolder.textView=(TextView)findViewById(R.id.text_view);

mView.setTag(viewHolder)://将ViewHolder存储到View中,setTag方法给View添加额外数据

}

else{

mView=convertView;

viewHolder=(ViewHolder) mView.getTag();//获取原先存储的ViewHolder

}

viewHolder.textView.setText("...");

return mView;

}

static class ViewHolder{//设置为静态,第一次加载会花费些时间,后面加载就方便了,而且只有一个ViewHolder,节省内存。

TextView textView;

}

}


扩展:关于上述代码的setTag()方法,一个例子(给Button添加额外的数据以判断是点击的是哪个Button)

public class MyActivity extends Activity implements View.OnClickListener{

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

setContentView(R.layout.main_layout);

Button button1=(Button)findViewById(...);

button1.setTag(1);

Button button2=(Button)findViewById(...);

button2.setTag(2);

button1.setOnClickListener(this):

button2.setOnClickListener(this):

}


public void onClick(View v){

switch(v.getTag()){
case 1:

Toast.makeText(MyActivity.this,"1",Toast.LENGTH.SHORT).show();

break;

case 2:

Toast.makeText(MyActivity.this,"2",Toast.LENGTH.SHORT).show();

break;



}

}

}



(3)由于用户滑动列表就会调用getView方法,所以getView方法不能做耗时操作,比如我们想在ListView里面显示我们从网站上获取的图片,加载图片的方法不能放在getView方法中,可以进行异步处理。


(4)对于第三点,在加载图片的情况下,当用户来回上下滑动,就会一瞬间产生很多异步任务,也就是很多UI的更新操作,UI的更新发生在主线程中,有可能造成界面卡顿,而且这些大量的异步任务会造成线程池的拥堵。

我们可以等用户滑动列表停下来时再进行加载图片。

给ListView设置setOnScrollListener,   利用OnScrollListener的onScrollStateChanged方法判断列表的状态,是滑动还是停止,如果是滑动就不加载图片,如果列表停止就加载图片。

listView.setOnScrollListener(new AbsListView.OnScrollListener){

public void onScrollStateChanged(AbsListView view,int scrollState){

if(scrollState==OnScrollListener.SCROLL_STATE_IDLE) {

isStop=true;

xxAdapter.notifyDataSetChanged();

else{

isStop=false;

}

}

}


然后在xxAdapter的getView方法中判断一下是否停止,停止时再加载图片。



(5)开启硬件加速,设置android:hardwareAccelerated="true"为活动开启硬件加速


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值