Search code examples
androidandroid-recyclerviewandroid-arrayadapterandroid-adapter

Sum method called multiple times in getview


I have a method that add days in the date of the listview, the problem is when I scroll down and up again the values are changed, I have 2 kinds of date, so the method has to be called when the second kind appears in the list, but how can I use the method once so it doesn't keep adding each time I scroll it?

     public class FaturasAdapter extends ArrayAdapter<Faturas> {

    private Activity activity;
    private LayoutInflater inflater;
    private List<Faturas> faturasItens;
    private Ferramentas mFerramentas;
    private String entrada;
    private String parcela = "";
    private Map<Integer, Integer> intervaloMap;
    private String data ="";


    public FaturasAdapter(Activity activity, RealmList<Faturas> inItems) {
        super(activity, R.layout.faturas_adapter, inItems);

        this.activity = activity;
        this.faturasItens = inItems;
        this.mFerramentas = new Ferramentas();
        this.intervaloMap = new HashMap<Integer, Integer>();

    }


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

    @Override
    public Faturas getItem(int location) {
        return faturasItens.get(location);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        View vi = convertView;
        final ViewHolder holder;
        final Faturas mFaturas = faturasItens.get(position);

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

            vi = inflater.inflate(R.layout.faturas_adapter, null);
            holder = new ViewHolder();

            holder.numero = (TextView) vi.findViewById(R.id.numero);
            holder.intervalo = (TextView) vi.findViewById(R.id.intervalo);
            holder.valor = (TextView) vi.findViewById(R.id.valor);
            holder.data = (TextView) vi.findViewById(R.id.data);

            vi.setTag(holder);




        } else {
            holder = (ViewHolder) vi.getTag();
        }
        addIntervalo(mFaturas.getIntervalo(), mFaturas.getTipo());
        data = mFerramentas.dataText(intervaloMap.get(mFaturas.getTipo()));
        holder.intervalo.setText(String.valueOf(mFaturas.getIntervalo()));

        if (mFaturas.getTipo() == Faturas.intervaloConstanteEntrada) {
            entrada = "ENT - ";
            holder.numero.setText(entrada + mFaturas.getOrder() + "/" + mFaturas.getQtParcelasEntrada());
            holder.valor.setText(String.valueOf(mFaturas.getValor()) + " ");

        } else {
            parcela = "PAR - ";
            holder.numero.setText(parcela + mFaturas.getOrder() + "/" + mFaturas.getQtParcela());
            holder.valor.setText(String.valueOf(mFaturas.getValor()) + " ");

        }

        holder.data.setText(data);
        return vi;
    }


    private void addIntervalo(int intervalo, int tipo) {
        int intervaloSum = intervalo;

        if (!intervaloMap.isEmpty()) {
            if (intervaloMap.get(tipo) != null)
                intervaloSum += intervaloMap.get(tipo);
        }

        intervaloMap.put(tipo, intervaloSum);

    }

    public List<Faturas> getfaturasItens() {
        return faturasItens;
    }

    public void setData(List<Faturas> fat) {
        this.faturasItens.addAll(fat);
        this.notifyDataSetChanged();
    }

    public class ViewHolder {
        TextView numero;
        TextView intervalo;
        TextView data;
        TextView valor;

    }

}

Solution

  • As I said in my comment I don't see why do you need to call the addIntervalo() method in the getView() method. The problem with this is that getView() will be called a lot as the user uses the ListView so you'll end up adding the same data again and again.

    From your code it seems you just show the data calculated with addIntervalo()(I'm assuming each item will present its data relative to the total that you calculate for that type that you calculate with addIntervalo()) so you could simply calculate in advance the values and then in getView() simply use that.

     // in the constructor you get the data so calculate the values
     // iterating over the data
     public FaturasAdapter(Activity activity, RealmList<Faturas> inItems) {
            super(activity, R.layout.faturas_adapter, inItems);
    
            this.activity = activity;
            this.faturasItens = inItems;
            this.mFerramentas = new Ferramentas();
            this.intervaloMap = new HashMap<Integer, Integer>();
            foreach(Faturas f : inItems) {
               addIntervalo(f.getIntervalo(), f.getTipo());
            }
        }
    

    You also have the setData() method where you update the data list so you also need to calculate the result of addIntervalo() for the new items that are about to be added to the adapter:

    public void setData(List<Faturas> fat) {
       // because you're adding the fat list to the current set of items
       // simply calculate addIntervalo() for them to add their count to the total
       foreach(Faturas f : fat) {
           addIntervalo(f.getIntervalo(), f.getTipo());
       }
       this.faturasItens.addAll(fat);
       this.notifyDataSetChanged();
    }
    

    In getView() remove the line:

    addIntervalo(mFaturas.getIntervalo(), mFaturas.getTipo());
    

    as you already calculated the values.