zoukankan      html  css  js  c++  java
  • ListView优化分页优化

    缘由

    我们在用ListView展现数据的时候。比如展现联系人,如果联系人太多就会出现卡的现象,比如如果有1000多条数据,从数据库里查询,然后装载到List容器这段时间是比较耗时的。虽然我们可以用asyncTask来单独开启一个子线程加载。一次查看那么多,未免有点多余。是否可以通过先装载30条数据,如果用户需要我们在继续查询并且展示后面的数据,这样一来可以提升。使用速率。

    实现方法

    1、数据库分页查询

    首先写SqlHelper指定每次查询数据库多少数据。代码如下

    /**
    * 分页查询黑名单
    *
    * @param limit
    * 限制数量
    * @param offset
    * 开始位置
    * @return
    */

    public List<BlackNumInfo> getPartBlackNum(int limit, int offset)
    {
    //查询返回的数据容器
    List<BlackNumInfo> blackNums = null;
    SQLiteDatabase db = dbHelper.getReadableDatabase();

    String[] columns = new String[] { NUM, MODE, ID };
    String selection = null;
    String[] selectionArgs = null;
    String groupBy = null;
    String having = null;
    String orderBy = null; // 排序功能
    String limitsr = offset + "," + limit; // 分页数据

    Cursor cursor = db.query(TABLE, columns, selection, selectionArgs, groupBy, having,
    orderBy, limitsr);
    //如果没有数据就返回View
    if (cursor.getCount() > 0)
    {
    blackNums = new ArrayList<BlackNumInfo>();
    }

    while (cursor.moveToNext())
    {
    String num = cursor.getString(0);
    int mode = cursor.getInt(1);
    int id = cursor.getInt(2);
    BlackNumInfo b = new BlackNumInfo(num, mode, id);
    blackNums.add(b);
    }

    db.close();
    dbHelper.close();
    return blackNums;
    }

    2. AsyncTask类的内部优化

    • 思路:每次开启一个异步任务查询数据。
    • 重置适配器中,数据容器的值,刷想适配器
    • ListView重绘
    /**
    * 异步加载
    */

    public void fillData()
    {
    new AsyncTask<String, Integer, String>()
    {

    // 程序运行前
    @Override
    protected void onPreExecute()
    {
    mLoadProgressBar.setVisibility(View.VISIBLE);
    // 显示加载进度
    super.onPreExecute();
    }

    // 程序运行时
    @Override
    protected String doInBackground(String... params)
    {
    // 查询 前30项的数据: 用子线程 ,
    if (mBlackNumList == null)
    {
    mBlackNumList = dao.getPartBlackNum(limit, offset);
    } else
    {
    // 如果不是第一次查询
    if (dao.getPartBlackNum(limit, offset) != null)
    {
    //把查询到的数据添加到容器中去
    mBlackNumList.addAll(dao.getPartBlackNum(limit, offset));
    }
    }

    return null;
    }

    // 运行后
    @Override
    protected void onPostExecute(String result)
    {
    //ProgressBar设置为不可见。
    mLoadProgressBar.setVisibility(View.INVISIBLE);

    if (adapter == null)
    {
    //第一次加载,创建适配器适配器
    adapter = new BlackNumAdapter(context, mBlackNumList);
    mBlackNumListView.setAdapter(adapter);
    } else
    {
    //第二次加载,适配器中容器数量
    adapter.setBlackNumList(mBlackNumList);
    //发送通知,适配器内容改变,从新加载
    adapter.notifyDataSetChanged();
    }
    }

    }.execute();
    }

    3.Adapter优化分页数据

    • 思路
    • convertView可回收视图的再次利用。
    • holderView类保存每次inflate出来View的子控件并保存在convertViewTag中。
    • 添加一个setDate()方法,重置容器数据

    public class BlackNumAdapter extends BaseAdapter
    {
    List<BlackNumInfo> mBlackNumList;
    Context context;
    BlackNumDao dao;

    public BlackNumAdapter(Context context, List<BlackNumInfo> mBlackNumList)
    {
    this.context = context;
    dao = new BlackNumDao(context);
    this.mBlackNumList = mBlackNumList;
    }

    public void setBlackNumList(List<BlackNumInfo> mBlackNumInfos)
    {
    this.mBlackNumList = mBlackNumInfos;
    }

    @Override
    public int getCount()
    {
    return mBlackNumList.size();
    }

    @Override
    public Object getItem(int position)
    {
    return mBlackNumList.get(position);
    }

    @Override
    public long getItemId(int position)
    {
    return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
    // 适配器的优化
    final BlackNumInfo numInfo = mBlackNumList.get(position);
    holderView hV = null;
    if (convertView == null)
    {
    hV = new holderView();
    convertView = LayoutInflater.from(context).inflate(R.layout.item_blacknum, parent,
    false);
    hV.modeTextView = (TextView) convertView.findViewById(R.id.tv_mode);
    hV.numberTextView = (TextView) convertView.findViewById(R.id.tv_number);
    hV.deleteImageView = (ImageView) convertView.findViewById(R.id.iv_deleteNumber);
    convertView.setTag(hV);
    } else
    {
    hV = (holderView) convertView.getTag();
    }

    hV.numberTextView.setText(mBlackNumList.get(position).getNum());

    String mode = "全部拦截";
    switch (numInfo.getMode())
    {
    case BlackNumDao.ALL:
    mode = "全部链接";
    break;
    case BlackNumDao.CLL:
    mode = "电话拦截";
    case BlackNumDao.SMS:
    mode = "短信拦截";
    default:
    break;
    }

    hV.modeTextView.setText(mode);
    hV.deleteImageView.setOnClickListener(new OnClickListener()
    {
    @Override
    public void onClick(View v)
    {
    // 删除功能
    dao.delete(numInfo.getNum() + "");
    mBlackNumList.remove(position);
    notifyDataSetChanged();
    }
    });
    return convertView;
    }

    }

    /**
    * 包装类
    * @author H_lang
    *
    */

    class holderView
    {
    public TextView modeTextView;
    public TextView numberTextView;
    public ImageView deleteImageView;
    }

    4.ListView滚动监听。

    • liseView设置滚动监听。
    • 重置分页查询的开始标度

    /**
    * 滚动状态改变的时候。
    */

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState)
    {
    // 根据滚动的状态来加载数据。
    if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL)
    {
    // 获得最后一次显示的数据
    int lastVisiblePosition = mBlackNumListView.getLastVisiblePosition();
    int size = mBlackNumList.size();

    if (lastVisiblePosition == size - 1)
    {
    //设置下次查询的开始位置。
    offset = limit + offset;
    fillData();
    }

    }

    }

    总结

    其中还是有许多的缺点。还有许多需要优化的功能。但是对于我现在学习的技术,没有想到更好的方法,希望以后我能继续优化,或者重写listView控件。

  • 相关阅读:
    POJ3094 UVALive3594 HDU2734 ZOJ2812 Quicksum【进制】
    UVALive5583 UVA562 Dividing coins
    POJ1979 HDU1312 Red and Black【DFS】
    POJ1979 HDU1312 Red and Black【DFS】
    POJ2386 Lake Counting【DFS】
    POJ2386 Lake Counting【DFS】
    HDU4394 Digital Square
    HDU4394 Digital Square
    UVA213 UVALive5152 Message Decoding
    UVA213 UVALive5152 Message Decoding
  • 原文地址:https://www.cnblogs.com/ganwei/p/4803932.html
Copyright © 2011-2022 走看看