ListView too slow to load XML

0

It's taking too long to load few items, it takes several seconds, and to load many items, it never loads. I used the same XML reading algorithm, with a simple list and loaded very fast, however in my custom ListView it takes a long time, I tried to use ViewHolder, but it did not work. Check out my classes:

Adapter

public class AdapterSegmento extends BaseAdapter {


private ArrayList<Segmento> itens;
private Activity myContext;
private LayoutInflater mLayoutInflater;
public AdapterSegmento(Context context, ArrayList<Segmento> itens) {
    //Itens que preencheram o listview
    this.itens = itens;
    //responsavel por pegar o Layout do item.

}

/**
 * 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 Segmento getItem(int position) {
    return itens.get(position);
}

/**
 * Sem implementação
 *
 * @param position
 * @return
 */

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


static class ViewHolder{
    TextView tvName;
    TextView tvDescription;
    ImageView imagem;
}
@Override
public View getView(int position, View view, ViewGroup parent) {

  View vi = view;             //trying to reuse a recycled view
  ViewHolder holder = null;

  if (vi == null) {
      //The view is not a recycled one: we have to inflate
      vi = mLayoutInflater.inflate(R.layout.empresa_item, parent, false);
      holder = new ViewHolder();

      holder.tvName = (TextView) vi.findViewById(R.id.nomeEmpresa);
      holder.tvDescription = (TextView) vi.findViewById(R.id.subtitulo);
     // holder.imagem = (ImageView) vi.findViewById(R.id.imagemSegmento);
      vi.setTag(holder);
  } else {
      // View recycled !
      // no need to inflate
      // no need to findViews by id
      holder = (ViewHolder) vi.getTag();
  }

 Segmento item = itens.get(position);

 holder.tvName.setText(item.getNome());
 holder.tvDescription.setText(item.getSubtitulo());
     return vi;
}
}

My View

public class SegmentoView extends Util implements OnItemClickListener {

private ListView listView;
private AdapterSegmento adapterEmpresa;
private ArrayList<Segmento> itensEmpresa;
XmlReader reader;
String URL;
ProgressDialog dialog;

@SuppressLint("NewApi") @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // carrega o layout onde contem o ListView
    setContentView(R.layout.empresa_lista);
    ActionBar bar = getActionBar();
    bar.hide();


    //Carregar XML
    reader = new XmlReader("http://www.itcuties.com/feed/");



    itensEmpresa = new ArrayList<Segmento>();
    try {
        for (int i = 0; i < reader.getItems().size(); ++i) {
            Segmento segmento = new Segmento();

            segmento.setNome(reader.getItems().get(i).getNome());
            segmento.setLink(reader.getItems().get(i).getLink());

            itensEmpresa.add(segmento);

        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    // Cria o adapter
    adapterEmpresa = new AdapterSegmento(this, itensEmpresa);

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

}
}

Can anyone help me?

    
asked by anonymous 26.12.2014 / 06:50

2 answers

1

Cause

The slowness in your case is due to the iteration of each iteration in the following section:

for (int i = 0; i < reader.getItems().size(); ++i) {
    // código omitido
}

For each iteration, the reader.getItems().size() method is called to be compared with the i , and for each call to the reader.getItems method a web query is performed.

Solution

Instead of calling such a method use a variable to store the return of reader.getItems and so the size of that list can be used in for . Staying like this:

items = reader.getItems();
itensEmpresa = new ArrayList<Segmento>();
try {
    for (int i = 0; i < items.size(); ++i) {
        Segmento segmento = new Segmento();

        segmento.setNome(items.get(i).getNome());
        segmento.setLink(items.get(i).getLink());

        itensEmpresa.add(segmento);
    }
} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
    
26.12.2014 / 22:01
0

Put NULL where parent is

BEFORE

 vi = mLayoutInflater.inflate(R.layout.empresa_item, parent, false);

AFTER

 vi = mLayoutInflater.inflate(R.layout.empresa_item, null, false);

You can also change this line to:

 vi = LayoutInflater.from(getContext(), R.layout.empresa_item, null);

Then you can check how much time you spend for this line:

//Carregar XML
    reader = new XmlReader("http://www.itcuties.com/feed/");

Using Log, for example:

 Log.d("teste",  new Date());
//Carregar XML
    reader = new XmlReader("http://www.itcuties.com/feed/");
Log.d("teste", new Date());

Obviously, you can get a better time in place of this new Date () that I used, but it was just to exemplify. Maybe the bottleneck is there.

You can use AsyncTask or AsyncTaskLoader to perform this load.

Here you can check how to use AsyncTask:

link

Here you can check how to use AsyncTaskLoader:

link

Study AndroidAnnotations.

link

It's even better than the default ViewHolder;)

Using Annotations in your Activity there, so you have an idea, nor would you need AsyncTask, as it would look like this:

ProgressDialog dialog;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // carrega o layout onde contem o ListView
    setContentView(R.layout.empresa_lista);
    ActionBar bar = getActionBar();
    bar.hide();

     // Cor quando a lista é selecionada para ralagem.
    listView.setCacheColorHint(Color.TRANSPARENT);


    dialog = new ProgressDialog(this);
    dialog.setMessage("Carregando dados...");
    dialog.show();

     //chamada para carregamento dos dados
     loadData();
}


@Background
void loadData(){

    //Carregar XML
    XmlReader reader = new XmlReader("http://www.itcuties.com/feed/");

    ArrayList itensEmpresa = new ArrayList<Segmento>();
    try {
        for (int i = 0; i < reader.getItems().size(); ++i) {
            Segmento segmento = new Segmento();

            segmento.setNome(reader.getItems().get(i).getNome());
            segmento.setLink(reader.getItems().get(i).getLink());

            itensEmpresa.add(segmento);

        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}


@UIThread
void createAdapter(ArrayList<Segmento> items){

    // Cria o adapter
    adapterEmpresa = new AdapterSegmento(this, items);
    // Define o Adapter
    listView.setAdapter(adapterEmpresa);

    dialog.dismiss();


}

(If you have any errors up there, give me a discount, because I did not put this to compile XD)

    
26.12.2014 / 19:13