0

我用一個viewpager(SmartTabLayout)與四個選項卡(片段)。在我使用自定義列表視圖的所有四個片段中。這些列表視圖爲每個項目從SD卡加載圖像。我使用Nostra's universal image loaderviewpager滯後listview有太多的項目時

一切工作正常。但是,當我將上述列表視圖中的項目數從10個增加到50個時,viewpager不再順利滑動。

我使用內存和光盤緩存的照片。這裏是我的形象裝載機的CONFIGS:

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(); 

以下是完整列表視圖適配器:

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; 
} 
} 
+0

您可以發佈您ListViewAdpater代碼? – cyroxis

回答

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的。
希望能解決問題:)

更新
對於那些誰想要使用PauseOnScrollListener在RecyclerView,這裏的nostra13的實現:https://gist.github.com/nostra13/806d01ebd604f3adf241

+0

我試過了RecyclerView,性能有了明顯的提升,但是現在滾動下來並向上滾動listview(receyclerView)laggs一下。你可以推薦什麼圖像加載器,或者配置效率低下? –

+0

當我需要做圖像加載(特別是通過HTTP)時,我通常使用[LruCache ](http://developer.android.com/training/displaying-bitmaps/index.html),實際上有有關在官方Android文檔中高效使用Bitmaps的信息堆。您可能也需要對圖像進行縮減採樣(使用NavigationView時,我遇到了類似的問題)。 – Patrick

+0

但是有沒有辦法用UIL實現這種效果?你能給我一點代碼示例如何使用上述緩存方法在ImageView中加載圖片嗎? –

1

與viewpagers的問題是,他們誇大目前的意見。如果你正在膨脹大量的資源,比如你現在正在做的事情,這可能會導致問題。我會建議充氣只是列表視圖,而不是所有的信息。您在活動中使用onPageSelected方法來調用方法來開始加載信息。這樣只會加載活動片段。如果您仍然不確定我的意思,請告訴我!

+0

其實這聽起來像問題是他的ListViews在他們需要它們之前加載圖像。 – cyroxis