c语言编程笔录

首页 >   > 笔记大全

笔记大全

怎么优化Android中的ListView

更新时间:2023-11-28

介绍

ListView是Android中最常用的控件之一,用于展示大量数据。但是随着数据量的增加,ListView的性能会出现问题,出现明显的卡顿和延迟,给用户带来不好的体验。因此需要对其进行优化,使其滑动流畅,响应迅速。

优化方式1:使用ViewHolder缓存控件

在ListView的getView()方法中,每次都是通过findViewById()来查找控件,造成了大量的资源浪费,使ListView滑动时出现卡顿。因此可以使用ViewHolder来缓存控件,以避免每次重复查找控件。


public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        holder = new ViewHolder();
        holder.textView = (TextView) convertView.findViewById(R.id.text_view);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.textView.setText(dataList.get(position));
    return convertView;
}

static class ViewHolder {
    TextView textView;
}

优化方式2:使用分页加载数据

如果ListView需要展示大量数据,为了避免在一次性加载过多数据,造成内存占用过高,可以使用分页加载数据的方式,每次加载适量的数据,避免数据过多导致ListView出现性能问题。


private int pageSize = 20;

private List getData(int page) {
    List dataList = new ArrayList<>();
    // TODO 从服务器获取数据,page为当前页数,pageSize为每页的数据量
    return dataList;
}

private void initListView() {
    final int[] currentPage = {1};
    final List dataList = new ArrayList<>();
    final ArrayAdapter adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, dataList);
    listView.setAdapter(adapter);
    listView.setOnScrollListener(new AbsListView.OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE
                    && listView.getLastVisiblePosition() == (adapter.getCount() - 1)) {
                currentPage[0]++;
                List newData = getData(currentPage[0]);
                if(newData.size() > 0) {
                    dataList.addAll(newData);
                    adapter.notifyDataSetChanged();
                } else {
                    Toast.makeText(context, "没有更多数据了", Toast.LENGTH_SHORT).show();
                }
            }
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

        }
    });
}


优化方式3:使用异步加载图片

在ListView中,如果需要加载图片,如果直接使用主线程加载图片,会导致UI线程卡顿。因此可以使用异步加载图片的方式,使加载图片的操作不影响主线程的执行,从而提升ListView的性能。


public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        holder = new ViewHolder();
        holder.imageView = (ImageView) convertView.findViewById(R.id.image_view);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
        holder.imageView.setImageResource(R.drawable.default_image);
    }

    String imageUrl = dataList.get(position).getImageUrl();
    holder.imageView.setTag(imageUrl);
    ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener() {

        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            if(view.getTag() != null && view.getTag().equals(imageUri)) {
                ((ImageView) view).setImageBitmap(loadedImage);
            }
        }
    });
    return convertView;
}

static class ViewHolder {
    ImageView imageView;
}

优化方式4:使用RecycleView代替ListView

ListView存在很多性能问题,因此在Android Lollipop中引入了RecyclerView,它支持更灵活的排列方式,并提高了渲染的效率和响应速度。




RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(new MyAdapter(dataList));

总之,在使用ListView时,需要关注数据量、布局、性能等问题,通过合理的优化措施,才能使ListView达到最佳的滑动流畅和响应迅速的效果。