在 getview 中多次调用 Sum 方法

Sum method called multiple times in getview

我有一个在列表视图的日期中添加天数的方法,问题是当我再次向下和向上滚动时值发生变化,我有 2 种日期,所以必须在第二种出现在列表中,但是我怎样才能使用该方法一次,这样它就不会在我每次滚动时都不断添加?

     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;

    }

}

正如我在评论中所说,我不明白为什么需要在 getView() 方法中调用 addIntervalo() 方法。这样做的问题是,当用户使用 ListView 时,getView() 将被调用很多次,因此您最终会一次又一次地添加相同的数据。

从您的代码看来,您似乎只显示了使用 addIntervalo() 计算的数据(我假设每个项目都会显示其数据相对于您为使用 addIntervalo() 计算的该类型计算的总数)所以您可以简单地预先计算值,然后在 getView() 中简单地使用它。

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

您还有更新数据列表的 setData() 方法,因此您还需要为即将添加到适配器的新项目计算 addIntervalo() 的结果:

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

在 getView() 中删除行:

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

因为您已经计算了值。

哦,基础 android 列表的小部件更改视图时出现问题。 您应该知道,ListView 和 RecycleView 每次滚动都会缓存和使视图无效!因此您的视图将更改为默认类型!

RecycleView 有解决方案,它使用方法 getItemType() 中的几种类型。但是您使用的是 ListView。反正!更好的解决方案是使用支持自定义视图并随时更改视图的特殊列表小部件。对于此任务,请使用 LinkedListView!