之后文本更改(可编辑的s)在Android中无法正常工作



我正在尝试创建一个应用程序,该应用程序在每个问题前面显示一些问题和EditText字段,一次显示答案。我遇到的问题是它不是 100% 准确的,有时它会接受错误的答案是正确的。我不完全确定这是否是我的逻辑有问题或方法。我尝试使用(Editable s)而不是EditText.getText(),这是最糟糕的事件。

public class AdapterListView extends ArrayAdapter<Questions> {
Context mContext;
LayoutInflater inflater;
private ArrayList<Questions> questionsArrayList;
private Questions quesObject;
private ArrayList<String> quesList = new ArrayList<String>();
int a, b, ab, c, d, cd, e, f, ef, g, h, gh, i, j, ij;
private ArrayList<Integer> answersList = new ArrayList<Integer>();
public AdapterListView(Context context, int resource, ArrayList<Questions> questionsArrayList) {
    super(context, resource);
    this.mContext = context;
    this.setQuestionsArrayList(questionsArrayList);
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.item_listview, null);
        holder = new ViewHolder();
        holder.questionTextView = convertView.findViewById(R.id.question);
        holder.editText = convertView.findViewById(R.id.ans_edit_text);
        holder.imgTrue = convertView.findViewById(R.id.ans_true);
        holder.imgFalse = convertView.findViewById(R.id.ans_false);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    quesObject = getQuestionsArrayList().get(position);
    Random rand = new Random();
    a = rand.nextInt(15) + 1;
    b = rand.nextInt(10) + 1;
    ab = a + b;
    c = rand.nextInt(15) + 1;
    d = rand.nextInt(10) + 1;
    cd = c + d;
    e = rand.nextInt(15) + 1;
    f = rand.nextInt(10) + 1;
    ef = e + f;
    g = rand.nextInt(15) + 1;
    h = rand.nextInt(10) + 1;
    gh = g + h;
    i = rand.nextInt(15) + 1;
    j = rand.nextInt(10) + 1;
    ij = i + j;
    quesList.add(a + " + " + b);
    quesList.add(c + " + " + d);
    quesList.add(e + " + " + f);
    quesList.add(g + " + " + h);
    quesList.add(i + " + " + j);
    answersList.add(ab);
    answersList.add(cd);
    answersList.add(ef);
    answersList.add(gh);
    answersList.add(ij);
    holder.questionTextView.setText("Q " + postion + ": t" + quesList.get(position));
    holder.editText.addTextChangedListener(new TextWatcher() {
        public void afterTextChanged(Editable s) {
                if (holder.editText.getText().toString().trim().length() > 0) {
                int inputNum = Integer.parseInt(String.valueOf(holder.editText.getText().toString().trim()));
                if (answersList.get(position) != inputNum) {
                    holder.imgFalse.setVisibility(View.VISIBLE);
                    holder.imgTrue.setVisibility(View.GONE);
                } else {
                    holder.imgTrue.setVisibility(View.VISIBLE);
                    holder.imgFalse.setVisibility(View.GONE);
                }
            }
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            getQuestionsArrayList().get(position).setQuestion(holder.editText.getText().toString());
        }
    });
    return convertView;
}
@Override
public int getCount() {
    return getQuestionsArrayList().size();
}
static class ViewHolder {
    TextView questionTextView;
    EditText editText;
    ImageView imgTrue, imgFalse;
}
}

这是因为适配器重用视图。假设您滚动并且索引 0 处的视图不再可见。适配器将重用索引 0 处的视图对象到接下来显示的任何视图。

每当发生这种情况时,您的代码都会通过holder.editText.addTextChangedListener添加新TextWatcher,而不会删除旧。

有多种

方法可以解决此问题,具体取决于您构建应用程序的方式。一种方法是将answersList作为清单。

private List<List<Integer>> answersList;
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) { // first time view is created
        convertView = inflater.inflate(R.layout.item_listview, null);
        holder = new ViewHolder();
        // TODO: initalize holder
        holder.editText.addTextWatcher(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                answers = answersList.get(i);
                for(Integer i: answers) {
                    // TODO: check answer
                }
            }
         });
    } else { // view is recycled
        holder = (ViewHolder) convertView.getTag();
    }
    holder.questionTextView.setText("Q " + postion + ": t" + quesList.get(position));
});

我正在使用它进行电子邮件文本验证。你可以看到这一点。我希望,它对你有所帮助。

mEmailView = findViewById(R.id.edit_email);
mEmailView.addTextChangedListener(new GenericTextWatcher(mEmailView));
public class GenericTextWatcher implements TextWatcher {
    private View view;
    private GenericTextWatcher(View view) {
        this.view = view;
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (isValidEmail(mEmailView.getText().toString().trim())) {
            mEmailView.setTextColor(Color.BLACK);
        } else {
            mEmailView.setTextColor(Color.RED);
        }
    }
    @Override
    public void afterTextChanged(Editable editable) {
        String text = editable.toString();
        String emailPattern = "[a-zA-Z0-9._-]+@[a-z]+\.+[net]+";
        switch (view.getId()) {
            case R.id.edit_email:
                if (!text.matches(emailPattern) || text.length() == 0) {
                    mEmailView.setError("JhonDoe@ati.net");
                }
                break;
        }
    }
    public boolean isValidEmail(CharSequence target) {
        return target != null && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
    }
}

最新更新