安卓开发,listview的优化,减少内存消耗,复用convertView、ViewHolder和分页加载

    xiaoxiao2025-06-13  14

    1:复用convertView,可以减少view对象的创建。adapter中的getview()方法会传经来一个convertView,convertView是指曾经使用过的view对象,可以被重复使用。但是使用之前要判断是否为空,否则可能会报空指针异常,不为空就直接复用,并作为getview方法的返回对象。 2:复用ViewHolder让其减少findViewById()次数,通过上面的代码可以看到,我们把findViewById找到的对象直接作为ViewHolder的属性赋值给他,然后convertView.setTag(holder);把ViewHolder的对象存储到convertView上,因为convertView是系统帮我们保存的,所以tag也会被保存,然后在复用convertView的时候也可以将上一次的findViewById找到的对象重复使用,这样大大提高了程序的运行效率。

    @Override public View getView(final int position, View convertView, final ViewGroup parent) { ViewHolder holder=null; //复用convertView if (convertView==null){ holder=new ViewHolder(); convertView = View.inflate(getApplicationContext(), R.layout.listview_blacknumber_item, null); holder.tv_phone = (TextView) convertView.findViewById(R.id.tv_phone); holder.tv_mode = (TextView) convertView.findViewById(R.id.tv_mode); holder.iv_delete = (ImageView) convertView.findViewById(R.id.iv_delete); convertView.setTag(holder); }else { //复用viewHolder holder= (ViewHolder) convertView.getTag(); } holder.iv_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //从数据库中删除 mDB.delete(mNumberInfoList.get(position).phone); //从集合中删除 mNumberInfoList.remove(position); //通知适配器刷新数据 if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } } }); listview条目的布局代码:

    //显示数据 holder. tv_phone.setText(mNumberInfoList.get(position).phone); switch (Integer.parseInt(mNumberInfoList.get(position).mode)) { case 1: holder.tv_mode.setText("拦截短信"); break; case 2: holder.tv_mode.setText("拦截电话"); break; case 3: holder.tv_mode.setText("拦截所有"); break; } return convertView; }

    3:static ViewHolder 在ViewHolder类加上static关键字,表示该类只指向一份指定的内存空间,不会创建多个对象,这是对ViewHolder对象创建过程中的一个优化。 4:分页算法 我们可以根据相应的业务需求,分多次加载条目个数,每次加载一个固定的条目,当用户滑动到本次加载条目的最后一条的时候,在继续加载剩下的数据,每次加载一个固定的条目个数,已到达优化的效果,下面我以加载数据库中的数据为例。

    //监听其滚动状态 lv_black_number.setOnScrollListener(new AbsListView.OnScrollListener() { //滚动过程中,状态发生改变调用方法() @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // OnScrollListener.SCROLL_STATE_FLING 飞速滚动 // OnScrollListener.SCROLL_STATE_IDLE 空闲状态 // OnScrollListener.SCROLL_STATE_TOUCH_SCROLL 拿手触摸着去滚动状态 if(mNumberInfoList!=null){ if (scrollState== AbsListView.OnScrollListener.SCROLL_STATE_IDLE&& //最后显示的条目的索引 lv_black_number.getLastVisiblePosition()>=mNumberInfoList.size()-1 &&!mIsLoad) { /*mIsLoad防止重复加载的变量 如果当前正在加载mIsLoad就会为true,本次加载完毕后,再将mIsLoad改为false 如果下一次加载需要去做执行的时候,会判断上诉mIsLoad变量,是否为false,如果为true,就需要等待上一次加载完成,将其值 改为false后再去加载*/ //如果条目总数大于集合大小的时,才可以去继续加载更多 if(mCount>mNumberInfoList.size()){ new Thread(){ @Override public void run() { //获取操作黑名单数据库的对象 mDB = BlackNumberDao.getInstance(getApplicationContext()); //查询部分数据 List<BlackNumberInfo> moreData = mDB.find(mNumberInfoList.size()); //把获得的数据添加到集合 mNumberInfoList.addAll(moreData); //通知适配器刷新数据 mHandler.sendEmptyMessage(0); } }.start(); } } } } //滚动过程中调用方法 @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } });
    转载请注明原文地址: https://ju.6miu.com/read-1299911.html
    最新回复(0)