安卓ListView

ListView 如何提高其效率

  1. 复用ConvertView
  2. 自定义静态类ViewHolder
  3. 使用分页加载
  4. 使用weakRefreence引用ImageView对象

ViewHolder为什么要申明为静态类

非静态内部类拥有对外部类对象是强引用,容易造成内存泄漏,所以申明成静态类

在Activity 中使用Handler 的时候如何去除警告信息

static class MyHandler extends Handler{
    private SoftReference srf;

    public MyHandler(Context context){
        srf = new SoftReference(context);
    }

    @Override
    public void handleMessage(Message msg) {
        Toast.makeText(srf.get(), msg.toString(), Toast.LENGTH_SHORT).show();
    }
}

ListView用了哪些设计模式

  1. 适配器
  2. 观察者
  3. 享元

ListView中的MVC思想

M: model

V: view

C: controller

当ListView 数据集改变后,如何更新ListView

ListView的adapter的notifyDataSetChanged()方法重新绘制ListView

ListView如何实现分页加载

  1. 设置ListView滚动监听器

     lv_content.setOnScrollListener(new OnScrollListener() {
         // 滚动状态发生变化调用
         @Override
         public void onScrollStateChanged(AbsListView view, int scrollState) {
             // SCROLL_STATE_IDLE: 静止状态
             // SCROLL_STATE_FLING: 滑翔
             // SCROLL_STATE_TOUCH_SCROLL: 手指按下移动
         }
         
         // 被滚动时调用
         @Override
         public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
         }
     });
    
  2. 分页加载只关心静止状态:当滚动停止时,如果最后一个条目是适配器数据集合中的最后一个数据则加载更多数据;当数据大于或等于总数量时候,提示用户没有更多数据了

ListView如何显示多类型条目

class MyAdapter extends BaseAdapter{

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

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

        TextView textView = new TextView(MainActivity.this);
        textView.setText(persons.get(position).toString());
        textView.setTextSize(16);
        
        return textView;
    }
    
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }
    
    // 根据不同ViewType加载不同布局
    @Override
    public int getViewTypeCount() {
        // TODO Auto-generated method stub
        return super.getViewTypeCount();
    }
    
    // 根据不同ViewType加载不同布局
    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        return super.getItemViewType(position);
    }
}

ListView 如何定位到指定位置

listView.setSelection(int);

如何在ScrollView 中如何嵌入ListView(待补)

在ScrollView 添加一个ListView 会导致listview 控件显示不全,通常只会显示一条,这是因为两个控件的滚动
事件冲突导致。所以需要通过listview 中的item 数量去计算listview 的显示高度,从而使其完整展示.

如:在ScrollView 中嵌套了ListView,ListView 展现的是物流状态。

ListView优化(图片优化,显示速度优化,滑动流畅度优化,内存优化)

图片优化

  1. 不要直接 BitmapFactory.decodeFile; 使用Options 保存图片大小,不要加载图片到内存

     Options opts = new Options();
     //不解析像素信息,只解析图片宽高,那么就不会申请内存去保存像素信息
     opts.inJustDecodeBounds = true;
     BitmapFactory.decodeFile("sdcard/dog.jpg", opts);
    
  2. 边界压缩(等比例缩小图片)图片,如果你的图片是后台服务器处理好的那就不需要了

     int imageWidth = opts.outWidth;
     int imageHeight = opts.outHeight;
     
     //获取屏幕宽高
     Display dp = getWindowManager().getDefaultDisplay();
    
     @SuppressWarnings("deprecation")
     int screenWidth = dp.getWidth();
     int screenHeight = dp.getHeight();
     
     //计算缩小比例
     int scale = 1;
     int scaleWidth = imageWidth / screenWidth;
     int scaleHeight = imageHeight / screenHeight;
    
     //取较大值
     if(scaleWidth >= scaleHeight && scaleWidth > 1){
         scale = scaleWidth;
     } else if(scaleWidth < scaleHeight && scaleHeight > 1){
         scale = scaleHeight;
     }
     
     //等比例缩小
     opts.inSampleSize = scale;
     //设置inJustDecodeBounds为false,不然位图工厂不会解析图片的所有像素信息,把像素信息保存在内存中
     opts.inJustDecodeBounds = false;
     //按照缩小后的比例来解析像素
     Bitmap bm = BitmapFactory.decodeFile("sdcard/dog.jpg", opts);
     
     ImageView iv = (ImageView) findViewById(R.id.iv);
     iv.setImageBitmap(bm);
    

内存优化

使用WeakReference来存储图片信息,比如可以使用WeakReference、SoftReference、WeakHashMap 等的来存储图片信息,避免内存溢出

在getView 中做图片转换时,产生的中间变量及时释放,避免内存泄漏

显示速度优化

异步加载图片(三级缓存)

  1. 先从内存缓存中获取图片显示(内存缓冲)
    • 先从内存加载,如果没有就开启子线程从SD卡或者请求网络
    • 在adapter中有个busy变量,表示listView是否处于滑动状态,如果是则仅仅从内存获取图片
  2. 获取不到的话从SD 卡里获取(SD 卡缓冲)
    • 边界压缩图片再保存
  3. 都获取不到的话从网络下载图片并保存到SD 卡同时加入内存并显示
    • 使用线程池ImageLoader加载图片,不要直接new一个线程下载图片

滑动流畅度优化

设置ListView滚动监听器,仅当滑动停止时才去加载图片

lv_content.setOnScrollListener(new OnScrollListener() {
    // 滚动状态发生变化调用
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // CROLL_STATE_IDLE: 静止状态
        // SCROLL_STATE_FLING: 滑翔
        // SCROLL_STATE_TOUCH_SCROLL: 手指按下移动
    }
    
    // 被滚动时调用
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    }
});

你可能感兴趣的:(安卓ListView)