listView内EditText的值在过滤时弄乱了

时间:2018-08-21 10:15:07

标签: java android

对于我的应用程序,我有一个ListActivity,它允许用户计算他们所看到的某个物种的标本数量。列表视图重新组合了所有物种,并且会有很多物种,所以我有自定义的筛选器来帮助我们。为此,我遵循了this的示例。我的活动就像this

问题是当我修改一个EditText和过滤器时,我修改过的所有项目上方的所有项目也都修改了他们的EditText。我想这是一个职位问题,但我尝试了不同的方法,无法解决。

编辑:显示错误的video

这是我的“自定义适配器”的代码:

package com.example.eden62.GENSMobile.Adapters.RNFAdapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.TextView;

import com.example.eden62.GENSMobile.Database.RNFDatabase.RNFInventaire;
import com.example.eden62.GENSMobile.R;

import java.util.ArrayList;

public class RNFInventaireAdapter extends ArrayAdapter<RNFInventaire>{

//La liste complète
private ArrayList<RNFInventaire> original;
//La liste contenant les inventaires filtrés
private ArrayList<RNFInventaire> fitems;
private ArrayList<RNFInventaire> items;
private Filter filterLat;
private Filter filterFr;

public RNFInventaireAdapter(Context context, @NonNull ArrayList<RNFInventaire> invs) {
    super(context, 0, invs);
    items = invs;
    original = new ArrayList<>(invs);
    fitems = new ArrayList<>(invs);
}

@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    if(convertView == null)
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_item_rnf_inventaires,parent,false);

    RNFInventaireViewHolder viewHolder = (RNFInventaireViewHolder) convertView.getTag();
    if(viewHolder == null){
        viewHolder = new RNFInventaireViewHolder();
        viewHolder.nomEspece = (TextView) convertView.findViewById(R.id.nomEspeceRNFInv);
        viewHolder.nombre = (EditText) convertView.findViewById(R.id.nombre);
        viewHolder.nbMale = (EditText) convertView.findViewById(R.id.nbMale);
        viewHolder.nbFemale = (EditText) convertView.findViewById(R.id.nbFemale);
        viewHolder.decNombreButton = (Button) convertView.findViewById(R.id.decDenombrement);
        viewHolder.incNombreButton = (Button) convertView.findViewById(R.id.incDenombrement);
        viewHolder.decNbMaleButton = (Button) convertView.findViewById(R.id.decNbMale);
        viewHolder.incNbMaleButton = (Button) convertView.findViewById(R.id.incNbMale);
        viewHolder.decNbFemaleButton = (Button) convertView.findViewById(R.id.decNbFemale);
        viewHolder.incNbFemaleButton = (Button) convertView.findViewById(R.id.incNbFemale);
    }

    final RNFInventaire inv = fitems.get(position);
    if(inv != null){
        final RNFInventaire invTest = original.get(original.indexOf(inv));
        String nom;
        String nomFr = invTest.getNomFr();
        nom = invTest.getNomLatin();

        if(!nomFr.isEmpty())
            nom += " - " + nomFr;

        viewHolder.nomEspece.setText(nom);

        viewHolder.nombre.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                int input = 0;
                try {
                    input = Integer.parseInt(s.toString());
                }catch (Exception e){
                    // e.printStackTrace();
                }
                invTest.setNombre(input);
            }

            @Override
            public void afterTextChanged(Editable s) { }
        });

        final RNFInventaireViewHolder finalViewHolder = viewHolder;
        viewHolder.nbMale.addTextChangedListener(new TextWatcher() {
            private int oldNbGenre;
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                oldNbGenre = invTest.getNbGenre();
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                int input = 0;
                try {
                    input = Integer.parseInt(s.toString());
                }catch (Exception e ){
                    // e.printStackTrace();
                }
                invTest.setNbMale(input);
                if(!isEmptyET(finalViewHolder.nombre))
                    updateDenombrementETViaNbGenre(oldNbGenre, invTest, finalViewHolder.nombre);
            }

            @Override
            public void afterTextChanged(Editable s) { }
        });

        viewHolder.nbFemale.addTextChangedListener(new TextWatcher() {
            private int oldNbGenre;
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    oldNbGenre = invTest.getNbGenre();
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                int input = 0;
                try {
                    input = Integer.parseInt(s.toString());
                }catch (Exception e) {
                    //  e.printStackTrace();
                }
                invTest.setNbFemale(input);
                if(!isEmptyET(finalViewHolder.nombre))
                    updateDenombrementETViaNbGenre(oldNbGenre, invTest, finalViewHolder.nombre);
            }

            @Override
            public void afterTextChanged(Editable s) { }
        });


        viewHolder.decNombreButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                decNombre(invTest, finalViewHolder.nombre);
            }
        });

        viewHolder.incNombreButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                incNombre(invTest, finalViewHolder.nombre);
            }
        });


        viewHolder.decNbMaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                decNbMale(invTest, finalViewHolder.nbMale);
            }
        });

        viewHolder.incNbMaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                incNbMale(invTest, finalViewHolder.nbMale);
            }
        });

        viewHolder.decNbFemaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                decNbFemale(invTest,finalViewHolder.nbFemale);
            }
        });

        viewHolder.incNbFemaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                incNbFemale(invTest,finalViewHolder.nbFemale);
            }
        });

        int nb = inv.getNombre();
        int nbMale = inv.getNbMale();
        int nbFemale = inv.getNbFemale();
        // Si le dénombrement n'a pas été défini
        if(nb != 0)
            viewHolder.nombre.setText(nb + "");
        else
            viewHolder.nombre.setText("");

        if(nbMale != 0)
            viewHolder.nbMale.setText(nbMale + "");
        else
            viewHolder.nbMale.setText("");

        if(nbFemale != 0)
            viewHolder.nbFemale.setText(nbFemale + "");
        else
            viewHolder.nbFemale.setText("");
    }

    return convertView;
}

private boolean isEmptyET(EditText et){
    return et.getText().toString().isEmpty();
}

/**
 * Met à jour le contenu de l'édit text dénombrement en fonction du total du genre. Si inférieur, le dénombrement est ramené au total
 * du nombre de genre. Si égal, le dénombrement suit les changement des dénombreemnt de genre
 *
 * @param oldNbGenre Ancien total du nombre de genre avant modification par l'utilisateur
 */
protected void updateDenombrementETViaNbGenre(int oldNbGenre, RNFInventaire inv, EditText nombre) {
    int nbGenre = inv.getNbGenre();
    int nb = inv.getNombre();
    boolean isInchoherantNb = nb < nbGenre;

    if(oldNbGenre > nbGenre && oldNbGenre == nb)
        nb -= (oldNbGenre - nbGenre);
    else {
        if (isInchoherantNb)
            nb = adjustNombre(inv);
    }
    String newString = "";
    if(nb > 0)
        newString += nb;
    nombre.setText(newString);
}

/**
 * Décrémente la valeure contenue dans un EditText, utile pour les différents dénombrements
 *
 * @param et L'editText à changer
 * @param nb La valeur à modifier
 * @return La valeur décrémenté de 1
 */
protected int decreaseDecompteEditText(EditText et, int nb){
    if(nb > 0) {
        String newText = "";
        nb--;
        if(nb > 0)
            newText += nb;
        et.setText(newText);
    }
    return nb;
}

private int adjustNombre(RNFInventaire inv){
    int nbGenre = inv.getNbGenre();
    int nb = inv.getNombre();
    if(nb < nbGenre)
        nb += nbGenre - nb;
    inv.setNombre(nb);
    return nb;
}

/**
 * Incrémente le dénombrement total de 1 et effectue une modification supplémentaire si le dénombrement est incohérant
 */
protected void incNombre(RNFInventaire inv, EditText nombre){
    adjustNombre(inv);
    int nb = inv.getNombre();
    nb ++;

    nombre.setText(nb + "");
}

/**
 * Décrémente le dénombrement total de 1
 */
protected void decNombre(RNFInventaire inv, EditText nombre){
    decreaseDecompteEditText(nombre,inv.getNombre());
}

/**
 * Incrémente de 1 le nombre de mâle
 */
protected void incNbMale(RNFInventaire inv, EditText nbMaleText){
    int nbMale = inv.getNbMale();
    nbMale ++ ;

    nbMaleText.setText(nbMale + "");
}

/**
 * Décrémente de 1 le nombre de mâle
 */
private void decNbMale(RNFInventaire inv, EditText nbMaleText){
   decreaseDecompteEditText(nbMaleText,inv.getNbMale());
}

/**
 * Incrémente de 1 le nombre de femelle
 */
private void incNbFemale(RNFInventaire inv, EditText nbFemaleText){
    int nbFemale = inv.getNbFemale();
    nbFemale ++;

    nbFemaleText.setText(nbFemale + "");
}

/**
 * Décrémente de 1 le nombre de femelle
 */
private void decNbFemale(RNFInventaire inv, EditText nbFemaleText){
    decreaseDecompteEditText(nbFemaleText,inv.getNbFemale());
}

public boolean allDenombrementAreCoherent(){
    for(RNFInventaire inv : original){
        if(!inv.hasCoherentDenombrement())
            return false;
    } return true;
}

public Filter getLatFilter() {
    if(filterLat == null)
        filterLat = new RNFInvLatinFilter();
    return filterLat;
}

public Filter getFrFilter() {
    if(filterFr == null)
        filterFr = new RNFInvFrFilter();
    return filterFr;
}

private abstract class RNFInvFilter extends Filter{

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults results = new FilterResults();
        String prefix = constraint.toString().toLowerCase();

        if(prefix == null || prefix.length() == 0){
            ArrayList<RNFInventaire> list = new ArrayList<>(original);
            results.values = list;
            results.count = list.size();
        }else {
            final ArrayList<RNFInventaire> list = new ArrayList<>(original);
            final ArrayList<RNFInventaire> nlist = new ArrayList<>();

            for(RNFInventaire inv : list){
                final String invName = getGoodNameFromInv(inv).toLowerCase();
                if(invName.startsWith(prefix))
                    nlist.add(inv);
            }
            results.values = nlist;
            results.count = nlist.size();
        }
        return results;
    }

    protected abstract String getGoodNameFromInv(RNFInventaire inv);

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        fitems = (ArrayList<RNFInventaire>)results.values;

        clear();
        addAll(fitems);
    }
}

private class RNFInvLatinFilter extends RNFInvFilter {

    @Override
    protected String getGoodNameFromInv(RNFInventaire inv) {
        return inv.getNomLatin();
    }
}

private class RNFInvFrFilter extends RNFInvFilter {

    @Override
    protected String getGoodNameFromInv(RNFInventaire inv) {
        return inv.getNomFr();
    }
}

private class RNFInventaireViewHolder {
    public TextView nomEspece;
    public EditText nombre, nbMale, nbFemale;
    public Button decNombreButton, incNombreButton, decNbMaleButton, incNbMaleButton, decNbFemaleButton, incNbFemaleButton;
}
}

RNFInventaire对象:

package com.example.eden62.GENSMobile.Database.RNFDatabase;
import android.os.Parcel;
import android.os.Parcelable;

public class RNFInventaire implements Parcelable{

protected String nomLatin;
protected String nomFr;
protected int nombre;
protected int nbMale;
protected int nbFemale;

public RNFInventaire(String nomLatin, String nomFr){
    this.nomLatin = nomLatin;
    this.nomFr = nomFr;
}

public RNFInventaire(String nomLatin, String nomFr, int nombre, int nbMale, int nbFemale) {
    this(nomLatin,nomFr);
    this.nombre = nombre;
    this.nbMale = nbMale;
    this.nbFemale = nbFemale;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(nomLatin);
    parcel.writeString(nomFr);
    parcel.writeInt(nombre);
    parcel.writeInt(nbMale);
    parcel.writeInt(nbFemale);
}

public static final Parcelable.Creator<RNFInventaire> CREATOR = new Parcelable.Creator<RNFInventaire>() {
    public RNFInventaire createFromParcel(Parcel in) {
        return new RNFInventaire(in);
    }

    public RNFInventaire[] newArray(int size) {
        return new RNFInventaire[size];
    }
};

private RNFInventaire(Parcel in) {
    nomLatin = in.readString();
    nomFr = in.readString();
    nombre = in.readInt();
    nbMale = in.readInt();
    nbFemale = in.readInt();
}

public String getNomLatin() {
    return nomLatin;
}

public void setNomLatin(String nomLatin) {
    this.nomLatin = nomLatin;
}

public String getNomFr() {
    return nomFr;
}

public void setNomFr(String nomFr) {
    this.nomFr = nomFr;
}

public int getNombre() {
    return nombre;
}

public void setNombre(int nombre) {
    this.nombre = nombre;
}

public int getNbMale() {
    return nbMale;
}

public void setNbMale(int nbMale) {
    this.nbMale = nbMale;
}

public int getNbFemale() {
    return nbFemale;
}

public void setNbFemale(int nbFemale) {
    this.nbFemale = nbFemale;
}

public int getNbGenre(){
    return nbMale + nbFemale;
}

public boolean hasCoherentDenombrement(){
    return nombre == 0 || (getNbGenre()) <= nombre;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    RNFInventaire that = (RNFInventaire) o;
    return nomLatin.equals(that.nomLatin) &&
            nomFr.equals(that.nomFr);
}

@Override
public int hashCode() {
    return nomLatin.hashCode();
}
}

希望你们能帮助我,谢谢!

1 个答案:

答案 0 :(得分:0)

通过@pskink示例,我能够更正我的错误,这是更正后的代码:

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.eden62.GENSMobile.Database.RNFDatabase.RNFInventaire;
import com.example.eden62.GENSMobile.R;
import com.example.eden62.GENSMobile.Tools.MatchableArrayAdapter;

public class RNFMatchableArrayAdapter extends MatchableArrayAdapter<RNFInventaire> {
    public RNFMatchableArrayAdapter(Context context, int resource, List<RNFInventaire> items) {
        super(context, resource);
        addAll(items);
    }
    public boolean latinFilterMode;

    @Override
    protected void onBind(final RNFInventaire item, View itemView, int position) {

        TextView nomEspece = (TextView) itemView.findViewById(R.id.nomEspeceRNFInv);
        final EditText nombre = (EditText) itemView.findViewById(R.id.nombre);
        final EditText nbMale = (EditText) itemView.findViewById(R.id.nbMale);
        final EditText nbFemale = (EditText) itemView.findViewById(R.id.nbFemale);
        Button decNombreButton = (Button) itemView.findViewById(R.id.decDenombrement);
        Button incNombreButton = (Button) itemView.findViewById(R.id.incDenombrement);
        Button decNbMaleButton = (Button) itemView.findViewById(R.id.decNbMale);
        Button incNbMaleButton = (Button) itemView.findViewById(R.id.incNbMale);
        Button decNbFemaleButton = (Button) itemView.findViewById(R.id.decNbFemale);
        Button incNbFemaleButton = (Button) itemView.findViewById(R.id.incNbFemale);

        bindNombreWatcher(nombre, item);
        bindNbMaleWatcher(nbMale, nombre, item);
        bindNbFemaleWatcher(nbFemale, nombre, item);

        String nom;
        String nomFr = item.getNomFr();
        nom = item.getNomLatin();

        if(!nomFr.isEmpty())
            nom += " - " + nomFr;

        nomEspece.setText(nom);

        decNombreButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                decNombre(item, nombre);
            }
        });

        incNombreButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                incNombre(item, nombre);
            }
        });


        decNbMaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                decNbMale(item, nbMale);
            }
        });

        incNbMaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                incNbMale(item, nbMale);
            }
        });

        decNbFemaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                decNbFemale(item,nbFemale);
            }
        });

        incNbFemaleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                incNbFemale(item,nbFemale);
            }
        });

        int nb = item.getNombre();
        int nbMaleInt = item.getNbMale();
        int nbFemaleInt = item.getNbFemale();
        // Si le dénombrement n'a pas été défini
        if(nb != 0)
            nombre.setText(nb + "");
        else
            nombre.setText("");

        if(nbMaleInt != 0)
            nbMale.setText(nbMaleInt + "");
        else
            nbMale.setText("");

        if(nbFemaleInt != 0)
            nbFemale.setText(nbFemaleInt + "");
        else
            nbFemale.setText("");
    }

    @Override
    protected boolean matches(RNFInventaire value, CharSequence constraint, CharSequence lowerCaseConstraint) {
        String itemName;
        if(latinFilterMode)
            itemName = value.getNomLatin().toLowerCase();
        else
            itemName = value.getNomFr().toLowerCase();
        return itemName.startsWith(lowerCaseConstraint.toString());
    }

    @Override
    protected void onViewCreated(View itemView) {
        final EditText nombre = (EditText) itemView.findViewById(R.id.nombre);
        final EditText nbMale = (EditText) itemView.findViewById(R.id.nbMale);
        final EditText nbFemale = (EditText) itemView.findViewById(R.id.nbFemale);

        NombreTW nombreTW = new NombreTW();
        NbFemaleTW nbFemaleTW = new NbFemaleTW(nombre);
        NbMaleTW nbMaleTW = new NbMaleTW(nombre);

        setWatcherToET(nombre, nombreTW);
        setWatcherToET(nbFemale, nbFemaleTW);
        setWatcherToET(nbMale, nbMaleTW);
    }

    private void setWatcherToET(EditText et, BaseTW tw){
        et.addTextChangedListener(tw);
        et.setTag(tw);
    }

    private void bindNombreWatcher(EditText nombre, RNFInventaire item){
        ((NombreTW) nombre.getTag()).item = item;
    }

    //
    private void bindNbMaleWatcher(EditText nbMale, EditText nombre, RNFInventaire item){
        ((NbMaleTW) nbMale.getTag()).item = item;
    }

    private void bindNbFemaleWatcher(EditText nbFemale, EditText nombre, RNFInventaire item){
        ((NbFemaleTW) nbFemale.getTag()).item = item;
    }

在listView活动中,我刚刚进行了更改

adapter = new RNFInventaireAdapter(this,myListOfItems);

进入

adapter = new RNFMatchableArrayAdapter(this, R.layout.row_item_rnf_inventaires,myListOfItems);

现在工作正常!

非常感谢@pskink

编辑:通过遵循MatchableArrayAdapter中的@pskink更改来更新代码