当listview获得太多项目时,viewpager会滞后

时间:2016-04-20 14:07:13

标签: android performance listview android-viewpager universal-image-loader

我正在使用带有四个标签(片段)的viewpager(SmartTabLayout)。在我使用自定义列表视图的所有四个片段中。这些列表视图从每个项目的SD卡加载图像。我使用Nostra's universal image loader

到目前为止一切正常。但是当我将上述一个列表视图中的项目数量从十个项目增加到大约五十个项目时,viewpager不再平滑滑动。

我使用内存和光盘缓存来拍照。以下是我的图像加载器配置:

File cacheDir = StorageUtils.getOwnCacheDirectory(context, 
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + Constants.DIRECTORY_TEAM_CHANNEL);//for caching

    ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
    config.diskCacheFileNameGenerator(new HashCodeFileNameGenerator());
    config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
    config.diskCache(new UnlimitedDiskCache(cacheDir)); // You can pass your own disc cache implementation
    config.memoryCacheSize(41943040);
    config.threadPoolSize(10);
    ImageLoader.getInstance().init(config.build());

我使用以下选项参数:

mImgDisplayOptions = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.drawable.default_user)
            .showImageForEmptyUri(R.drawable.default_user)
            .showImageOnFail(R.drawable.default_user)
            .cacheInMemory(true)
            .cacheOnDisc(true)
            .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
            .build();

这是完整的listview适配器:

public class CustomContactListAdapter extends BaseAdapter
{
private static final int TYP_REGISTERED = 0;
private static final int TYP_UNREGISTERED = 1;
private static final int VIEW_TYPE_COUNT = 2;

private Activity activity;
private List<User> userItems;
private DisplayImageOptions mOptions;

private DBHandler dbHandler;
private DisplayImageOptions mImgDisplayOptions;

static ImageLoader imageLoader = ImageLoader.getInstance();

public CustomContactListAdapter(Activity activity, List<User> userItems)
{
    this.activity = activity;
    this.userItems = userItems;
    dbHandler = DBHandler.getInstance(activity.getApplicationContext());


    mImgDisplayOptions = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.drawable.default_user)
            .showImageForEmptyUri(R.drawable.default_user)
            .showImageOnFail(R.drawable.default_user)
            .cacheInMemory(true)
            .cacheOnDisc(true)
            .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
            .build();
}

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

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

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

@Override
public int getItemViewType(int position) 
{
    return (userItems.get(position).getToken() != null) ? TYP_REGISTERED : TYP_UNREGISTERED;
}

@Override
public int getViewTypeCount()
{
    return VIEW_TYPE_COUNT;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    ViewHolder viewholder=null;
    int type = getItemViewType(position);    

    if (convertView == null)
    {    
        viewholder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);


        switch(type)
        {
            case TYP_REGISTERED:

                convertView = inflater.inflate(R.layout.contact_list_row, parent, false);
                viewholder.thumbNail = (ImageView ) convertView.findViewById(R.id.thumbnail_reg);
                viewholder.name = (TextView) convertView.findViewById(R.id.name_reg);
                viewholder.lastComment = (TextView) convertView.findViewById(R.id.lastComment_reg);
                viewholder.regState = (TextView) convertView.findViewById(R.id.regState_reg);

                viewholder.thumbNail.setMaxHeight(60);
                viewholder.thumbNail.setMaxWidth(60);
                break;

            case TYP_UNREGISTERED:

                convertView = inflater.inflate(R.layout.contact_list_not_registered_row, parent, false);
                viewholder.thumbNail = (ImageView) convertView.findViewById(R.id.thumbnail_not_reg);
                viewholder.name = (TextView) convertView.findViewById(R.id.name_not_reg);
                viewholder.phonenumber = (TextView) convertView.findViewById(R.id.phonenumber_not_reg);
                viewholder.regState = (TextView) convertView.findViewById(R.id.regState_not_reg);

                viewholder.thumbNail.setMaxHeight(60);
                viewholder.thumbNail.setMaxWidth(60);
                break;
        }

        convertView.setTag(viewholder);            
    }
    else
    {
        viewholder = (ViewHolder) convertView.getTag();
    }

    // getting user data for the row
    User user = userItems.get(position);
    String userName = "";

    switch(type)
    {
        case TYP_REGISTERED:
        {
            //thumbnail
            if (user.getThumbnail() != null)
            {
                if(user.getThumbnail() != null)
                {
                    imageLoader.displayImage(Constants.ABS_PATH_USER_THUMBNAIL + user.getThumbnail() + ".jpg", viewholder.thumbNail, mImgDisplayOptions);
                }
                else
                {
                    viewholder.thumbNail.setImageResource(R.drawable.default_user);
                }
            }
            else
            {
                viewholder.thumbNail.setImageResource(R.drawable.default_user);
            }

            //firstname
            if (user.getFirstname() != null) {
                userName += user.getFirstname() + " ";
            }

            //lastname
            if (user.getLastname() != null) {
                userName += user.getLastname();
            }
            viewholder.name.setText(userName);


            Chat chat = dbHandler.getChatByUser(user);
            if (chat != null) {
                Comment lastComment = dbHandler.getLastCommentFromUser(chat, user);

                if (lastComment != null) {
                    viewholder.lastComment.setText((lastComment.getContent().length() > 25)
                            ? lastComment.getContent().substring(0, 25) + "..." : lastComment.getContent());
                } else {
                    viewholder.lastComment.setText("");
                }

            } else {
                viewholder.lastComment.setText("");
            }


            // registration state (registered)
            viewholder.regState.setText(String.valueOf("mobil"));

            break;
        }
        case TYP_UNREGISTERED:
        {
            if (user.getThumbnail() != null)
            {

                if(user.getThumbnail() != null)
                {
                    imageLoader.displayImage(Constants.ABS_PATH_USER_THUMBNAIL + user.getThumbnail() + ".jpg", viewholder.thumbNail, mImgDisplayOptions);
                }
                else
                {
                    viewholder.thumbNail.setImageResource(R.drawable.default_user);
                }
            }
            else
            {
                viewholder.thumbNail.setImageResource(R.drawable.default_user);
            }

            if (user.getFirstname() != null) {
                userName += user.getFirstname() + " ";
            }

            if (user.getLastname() != null) {
                userName += user.getLastname();
            }

            viewholder.name.setText(userName);


            // phonenumber
            viewholder.phonenumber.setText(user.getPhonenumber());

            // registration state (unregistered, send invitation)
            viewholder.regState.setText(String.valueOf("Einladen"));

            break;
        }
    }

    return convertView;
}

private static class ViewHolder
{
    ImageView thumbNail;
    TextView name;
    TextView phonenumber;
    TextView lastComment;
    TextView regState; 
}
}

2 个答案:

答案 0 :(得分:1)

viewpagers的问题在于它们会在当前视图之前夸大视图。如果您正在膨胀大量资源(例如您现在正在执行的操作),这可能会导致问题。我建议只扩展listview而不是所有信息。您在活动中使用onPageSelected方法来调用方法以开始加载信息。这样只加载活动片段。如果你仍然不确定我的意思,请告诉我!

答案 1 :(得分:1)

ListViews在滚动屏幕时不会回收他们的视图。拥有大量片段,每个在ListView中渲染图像都会非常昂贵。

如果您想避免滞后,请查看RecyclerView。它们记录完备,易于实施,HEAPS效率更高。

<强>更新
我注意到你在滚动时正在加载图像(我认为这不会是一个问题,因为它应该异步加载)。

根据文档,您可以在通过PauseOnScrollListener滚动ListViews时暂停加载 要避免列表(网格,...)滚动滞后,您可以使用PauseOnScrollListener:

boolean pauseOnScroll = false; // or true
boolean pauseOnFling = true; // or false
PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
listView.setOnScrollListener(listener);

直接从Useful Info UIL Documentation中取出。希望能解决问题:)

<强>更新
对于那些想在RecyclerView上使用PauseOnScrollListener的人来说,这是nostra13的实现:https://gist.github.com/nostra13/806d01ebd604f3adf241