对于我的应用程序,我有一个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();
}
}
希望你们能帮助我,谢谢!
答案 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更改来更新代码