Very slow listview on scroll bar

Asked

Viewed 294 times

4

I have a problem I don’t know how to solve, I have a ListView customized with images and the scroll bar keeps crashing, even with the list loaded. It slows down the list to scroll.

Adapter:

public class AdapterSegmento extends BaseAdapter {

private LayoutInflater mInflater;
private ArrayList<Categoria> itens;

public AdapterListView(Context context, ArrayList<Categoria> itens) {
    //Itens que preencheram o listview
    this.itens = itens;
    //responsavel por pegar o Layout do item.
    mInflater = LayoutInflater.from(context);
}

/**
 * Retorna a quantidade de itens
 *
 * @return
 */
public int getCount() {
    return itens.size();
}

/**
 * Retorna o item de acordo com a posicao dele na tela.
 *
 * @param position
 * @return
 */
public Categoria getItem(int position) {
    return itens.get(position);
}

/**
 * Sem implementação
 *
 * @param position
 * @return
 */
public long getItemId(int position) {
    return position;
}

public View getView(int position, View view, ViewGroup parent) {
    //Pega o item de acordo com a posção.
    Categoria item = itens.get(position);
    //infla o layout para podermos preencher os dados
    view = mInflater.inflate(R.layout.item_list, null);

    //atravez do layout pego pelo LayoutInflater, pegamos cada id relacionado
    //ao item e definimos as informações.
    ((TextView) view.findViewById(R.id.text)).setText(item.getTexto());
    ((ImageView) view.findViewById(R.id.imagemview)).setImageResource(item.getIconeRid());
  //  ((TextView) view.findViewById(R.id.subtitulo)).setText(item.getSubtitulo());

    return view;
}

Class filling the list:

private void gerarLista() {

    itens = new ArrayList<Categoria>();

    String[] categorias = getResources().getStringArray(R.array.categorias);
    String[] drawableCategorias = getResources().getStringArray(
            R.array.categorias_drawable);

    listView.setScrollingCacheEnabled(false);

    // Vai recuperar os dois array's la do strings.xml e iterar sobre eles e criar os itens
    for (int i = 0; i < categorias.length; ++i) {
        itens.add(new Categoria(categorias[i], getResources()
                .getIdentifier(drawableCategorias[i], "drawable",
                        this.getPackageName())));
    }

    // Criamos uma lista que preenchera o ListView
    /*
     * itens = new ArrayList<Categoria>(); Categoria item1 = new
     * Categoria("Alimentação", R.drawable.alimentacao); Categoria item2 =
     * new Categoria("Esporte", R.drawable.esporte);
     * 
     * itens.add(item1); itens.add(item2);
     */
    // Cria o adapter
    adapterListView = new AdapterListView(this, itens);

    // Define o Adapter
    listView.setAdapter(adapterListView);
    // Cor quando a lista é selecionada para ralagem.
    listView.setCacheColorHint(Color.TRANSPARENT);
}

How to solve this?

  • What’s in the classes Segmento and Categoria?

  • hello, I changed the post because Adapter was wrong, there is no Segment class, only category.Well, Category is just a class where it contains Title, and Image, and the get and set, is just a model form.

  • After scrolling the list all images remain loaded and the scrolling gets better?

  • No, it’s always slow even when the images are loaded.

  • It’s probably the image’s code. Already tried to put the line ((ImageView) view.findViewById(R.id.imagemview)).setImageResource(item.getIconeRid()); within a AsyncTask?

1 answer

4

The problem lies in the architecture of your algorithm. With each iteration in the method getView() of Adapter you are inflating to view you want. This is bad practice!

You need to use the design standard Holder, which will store the references statically from your Views and will improve performance. Also, if you notice, the method getView() receives as parameter a View (view) that is nothing more than the View that you return in this method itself, that is, they use the recursive methodology.

A very basic example of the Holder pattern would be:

public static class ViewHolder {
  TextView hTextViewName;
}

public View getView(int position, View view, ViewGroup parent) {
  ViewHolder holder;
  if (view == null) {
    holder = new ViewHolder();
    view = LayoutInflater.from(context).inflate(R.layout.view_to_inflate, parent, false);
    holder.hTextViewName = (TextView) view.findViewById(R.id.textView_name);
    view.setTag(holder);
  } else {
    holder = (ViewHolder) view.getTag();
  }

  String name = getItem(position);
  holder.hTextViewName.setText(name);

  return view;
}

You can tell the difference! This way you will have much more performance.

In short, from the above case you just need to adapt it to your context! :-)

  • You can check out more fun facts about Listview performance on the Android website: http://developer.android.com/training/improving-layouts/smooth-scrolling.html

  • but that would be on Adapter? Can you show me how to apply to my model? Because I’m not getting it. Thank you

  • Clara, it is on your Adapter yes! Note that I am using the same method as you "getView()". You just need to add Imageview to my Viewholder and instantiate the Views variable in Viewholder. There is no secret, just analyze the code and understand!

  • Clara, did you get your Adapter to perform? Look at this video I made a long time ago http://debugcodigos.blogspot.com.br/2012/05/adapter-efficientlyandroid.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.