【问题标题】:Loading Gridview is choppy加载 Gridview 时断断续续
【发布时间】:2016-12-06 19:37:41
【问题描述】:

我正在尝试使用包含产品信息的卡片加载网格视图。

我不确定这是否是处理此类数据加载的最佳方式。

首先我要设置我的适配器:

cardView.setAdapter(new productCardAdapter(getActivity(),products));

Products 是一个包含产品对象的对象,产品对象内部具有图像、名称、价格等值。

在我的public class productCardAdapter extends BaseAdapter

我设置产品

this.products = products;

然后在

public View getView(int i, View view, ViewGroup viewGroup) {

我正在根据索引 i 设置值

if(view == null){

    // CREATE NEW
    view = inflater.inflate(R.layout.product_card,null);

    // GET CURRENT PRODUCT
    Products.Product product = products.products.get(i);

    // CREATE WIDGETS
    TextView cardTitle = (TextView)view.findViewById(R.id.txtProductName);
    ImageView cardImage = (ImageView)view.findViewById(R.id.imgProductImage);
    CardView card = (CardView)view.findViewById(R.id.tmpCard);
    TextView cardSKU = (TextView)view.findViewById(R.id.txtProductSKU);
    TextView cardPrice = (TextView)view.findViewById(R.id.txtProductPrice);

    // GET IMAGE
    if (product.picture.length() > 0) {

        // PUT IMAGE
        cardImage.setImageBitmap(BitmapFactory.decodeFile(functions.getLocalPicturePath(product.picture)));

    }else{

        // GENERATE GRADIENT
        card.setBackground(colors.generateGradient());

    }


    // SET VALUES
    cardTitle.setText(product.name);
    cardSKU.setText(product.sku);

    cardPrice.setText("$"+product.price);

    // CHECK FOR SALE PRICE
    if(product.salePrice > 0){
        cardPrice.setText("$"+product.salePrice);
    }

}

return view;

加载时会出现持续接近 1 秒的断断续续的过渡。

有什么方法可以改进吗?

【问题讨论】:

  • cardImage.setImageBitmap 是耗时的。考虑一个延迟加载库

标签: android gridview


【解决方案1】:

首先,enable StrictMode。然后它会告诉你你正在主应用程序线程上进行磁盘 I/O。它不会对您大喊大叫,您正在主应用程序线程上执行昂贵的位图解码操作,尽管这也是一个问题。

然后,按照 njzk2 的建议,使用 the vast array of image-loading libraries for Android 之一,例如 Picasso,异步加载您的图像。

【讨论】:

    【解决方案2】:

    Google 的示例代码 https://developer.android.com/guide/topics/ui/layout/gridview.html 树立了一个坏榜样

    修复该示例代码,而不是:

    imageView.setImageResource(mThumbIds[position]);
    

    您需要使用一个库(我使用 Glide)在线程中加载图像。像这样:

    public View getView(int position, View convertView, ViewGroup parent) {
        CircleImageView imageView;
    
        if (convertView == null) {
            // not recycled
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_image, parent, false);
            imageView = (CircleImageView) view;
        } else {
            // recycled
            imageView = (CircleImageView) convertView;
        }
    
        Glide
                .with(parent.getContext())
                .load(mThumbIds[position])
                .placeholder(R.mipmap.ic_launcher)//REQUIRED
                .dontAnimate()//REQUIRED
                .into(imageView);
    
        //imageView.setImageResource(mThumbIds[position]);
    
        return imageView;
    }
    

    在此处获取 CircleImageView:https://github.com/hdodenhof/CircleImageView 在这里获取滑翔:https://github.com/bumptech/glide

    顺便说一下,我的R.layout.item_image 的 XML 是:

    <?xml version="1.0" encoding="utf-8"?>
    
    <de.hdodenhof.circleimageview.CircleImageView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/image_avatar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        app:civ_border_width="1dp"
        app:civ_border_color="#FF000000"/>
    

    【讨论】:

      最近更新 更多