0

Ich verwende einen Viewpager (SmartTabLayout) mit vier Registerkarten (Fragmente). In allen vier Fragmenten verwende ich benutzerdefinierte Listenansichten. Diese Listenansichten laden Bilder von SD-Karte pro Artikel. Ich benutze dafür Nostra's universal image loader.ViewPager Verzögerung, wenn ListView zu viele Elemente

Alles funktioniert gut so weit. Aber wenn ich die Anzahl der Items in einer der oben genannten Listenansichten von zehn auf ungefähr fünfzig Items erhöhe, wischt der Viewpager nicht mehr reibungslos.

Ich verwende Speicher und Disc-Caching für Bilder. Hier meine configs von Bild loader sind:

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

Und ich verwende folgende Option Parameter:

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

Hier ist die komplette Listview-Adapter:

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

Können Sie Ihren ListViewAdpater Code posten? – cyroxis

Antwort

1

ListViews recyceln ihre Ansichten nicht, wenn sie vom Bildschirm scrollen. Viele Fragmente, die jeweils Bilder in einem ListView darstellen, können sehr teuer sein.

Werfen Sie einen Blick in die RecyclerView, wenn Sie Lag vermeiden möchten. Sie sind recht gut dokumentiert, einfach zu implementieren und HEAPS effizienter.

Update:
bemerkte ich, dass Sie, dass Sie Bilder sind geladen, während Sie blättern (die ich kein Problem wäre, dachte, da es asynchron geladen werden sollte).

Gemäß der Dokumentation können Sie den Ladevorgang anhalten, während Sie ListViews über die PauseOnScrollListener scrollen.
Zur Vermeidung Liste (Gitter, ...) Scrollen hinkt Sie PauseOnScrollListener verwenden können:

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

Nahm, dass gerade aus dem Useful Info UIL Documentation.
Hoffentlich, die das Problem löst :)

aktualisieren
Für diejenigen, die PauseOnScrollListener auf einem RecyclerView verwenden möchten, hier ist die Umsetzung des nostra13: https://gist.github.com/nostra13/806d01ebd604f3adf241

+0

Ich habe versucht, die RecyclerView und die Leistung hat sich offensichtlich verbessert, aber jetzt beim Scrollen nach unten und oben die Listview (recyclerView) lags ein wenig. Welchen Image Loader können Sie empfehlen oder sind die Konfigurationen ineffizient eingestellt? –

+0

Wenn ich Bild laden muss (vor allem über HTTP) verwende ich normalerweise einen [LruCache ] (http://developer.android.com/training/displaying-bitmaps/index.html), da ist eigentlich ein Heap von Informationen zur effizienten Verwendung von Bitmaps in der offiziellen Android-Dokumentation. Sie müssen möglicherweise auch Ihre Bilder nach unten sampeln (ich hatte ein ähnliches Problem bei der Verwendung der NavigationView). – Patrick

+0

Aber gibt es eine Möglichkeit, diesen Effekt mit UIL zu erreichen? Können Sie bitte ein kleines Codebeispiel geben, wie Sie ein Bild in einem ImageView mit der oben genannten Caching-Methode laden? –

1

Das Problem mit viewpagers ist, dass sie aufzublasen Ansichten vor dem aktuellen. Dies kann Probleme verursachen, wenn Sie Tonnen von Ressourcen aufblasen, wie zum Beispiel, was Sie gerade tun. Ich würde empfehlen, nur die Listview aufzublasen anstatt alle Informationen. Sie verwenden die onPageSelected-Methode in Ihrer Aktivität, um eine Methode aufzurufen, um mit dem Laden der Informationen zu beginnen. Auf diese Weise wird nur das aktive Fragment geladen. Wenn Sie immer noch nicht sicher sind, was ich meine, lassen Sie es mich wissen!

+0

Eigentlich hört sich das so an, als ob seine ListViews Bilder laden, bevor sie sie brauchen. – cyroxis