java - android على Text Change Listener




android-textview onchange (4)

لدي موقف ، حيث يوجد حقلين. field1 و field2 . كل ما أريد فعله هو field2 فارغ عندما يتم تغيير field1 والعكس بالعكس. في النهاية ، يحتوي حقل واحد فقط على محتوى.

field1 = (EditText)findViewById(R.id.field1);
field2 = (EditText)findViewById(R.id.field2);

field1.addTextChangedListener(new TextWatcher() {

   public void afterTextChanged(Editable s) {}

   public void beforeTextChanged(CharSequence s, int start,
     int count, int after) {
   }

   public void onTextChanged(CharSequence s, int start,
     int before, int count) {
      field2.setText("");
   }
  });

field2.addTextChangedListener(new TextWatcher() {

   public void afterTextChanged(Editable s) {}

   public void beforeTextChanged(CharSequence s, int start,
     int count, int after) {
   }

   public void onTextChanged(CharSequence s, int start,
     int before, int count) {
     field1.setText("");
   }
  });

يعمل بشكل جيد إذا قمت بإرفاق addTextChangedListener إلى field1 فقط ، ولكن عندما أفعل ذلك لكلا الحقلين يتعطل التطبيق. من الواضح أنهم يحاولون تغيير بعضهم البعض إلى أجل غير مسمى. بمجرد أن يتغير field1 فإنه يمسح field2 في هذا المجال field2 يتم تغييره حتى يتم مسح field1 وهكذا ...

يمكن لأي شخص أن يقترح أي حل؟


أعلم أن هذا شيئ قديم لكن شخص ما قد يواجه هذا الأمر في يوم من الأيام.

كان لدي مشكلة مماثلة حيث كنت أسمي setText على EditText و سوف يتم استدعاء onTextChanged عندما لا أريد ذلك. كان الحل الأول لي كتابة بعض التعليمات البرمجية بعد استدعاء setText () للتراجع عن الضرر الذي يحدثه المستمع. لكن هذا لم يكن أنيقًا للغاية. بعد إجراء بعض الأبحاث والاختبارات ، اكتشفت أن استخدام getText (). clear () يمسح النص بنفس الطريقة التي يتم بها ضبط setText ("") ، ولكن نظرًا لأنه لا يقوم بتعيين النص الذي لا يستدعيه المستمع ، حل مشكلتي. لقد قمت بتحويل جميع استدعائي setText ("") إلى getText (). قم بإلغاء تحديد () ولم أكن بحاجة إلى الضمادات بعد الآن ، لذلك ربما سيؤدي ذلك إلى حل مشكلتك أيضًا.

جرب هذا:

Field1 = (EditText)findViewById(R.id.field1);
Field2 = (EditText)findViewById(R.id.field2);

Field1.addTextChangedListener(new TextWatcher() {

   public void afterTextChanged(Editable s) {}

   public void beforeTextChanged(CharSequence s, int start,
     int count, int after) {
   }

   public void onTextChanged(CharSequence s, int start,
     int before, int count) {
      Field2.getText().clear();
   }
  });

Field2.addTextChangedListener(new TextWatcher() {

   public void afterTextChanged(Editable s) {}

   public void beforeTextChanged(CharSequence s, int start,
     int count, int after) {
   }

   public void onTextChanged(CharSequence s, int start,
     int before, int count) {
     Field1.getText().clear();
   }
  });

تأخر قليلاً في الإجابة ، ولكن هنا حل قابل لإعادة الاستخدام:

/**
 * An extension of TextWatcher which stops further callbacks being called as 
 * a result of a change happening within the callbacks themselves.
 */
public abstract class EditableTextWatcher implements TextWatcher {

    private boolean editing;

    @Override
    public final void beforeTextChanged(CharSequence s, int start, 
                                                    int count, int after) {
        if (editing)
            return;

        editing = true;
        try {
            beforeTextChange(s, start, count, after);
        } finally {
            editing = false;
        }
    }

    protected abstract void beforeTextChange(CharSequence s, int start, 
                                                     int count, int after);

    @Override
    public final void onTextChanged(CharSequence s, int start, 
                                                int before, int count) {
        if (editing)
            return;

        editing = true;
        try {
            onTextChange(s, start, before, count);
        } finally {
            editing = false;
        }
    }

    protected abstract void onTextChange(CharSequence s, int start, 
                                            int before, int count);

    @Override
    public final void afterTextChanged(Editable s) {
        if (editing)
            return;

        editing = true;
        try {
            afterTextChange(s);
        } finally {
            editing = false;
        }
    }

    public boolean isEditing() {
        return editing;
    }

    protected abstract void afterTextChange(Editable s);
}

لذلك عندما يتم استخدام ما سبق ، فإن أي استدعاءات setText() تحدث داخل TextWatcher لن ينتج عنها استدعاء TextWatcher مرة أخرى:

/**
 * A setText() call in any of the callbacks below will not result in TextWatcher being 
 * called again.
 */
public class MyTextWatcher extends EditableTextWatcher {

    @Override
    protected void beforeTextChange(CharSequence s, int start, int count, int after) {
    }

    @Override
    protected void onTextChange(CharSequence s, int start, int before, int count) {
    }

    @Override
    protected void afterTextChange(Editable s) {
    }
}

لقد واجهت نفس المشكلة أيضًا واستمر في الحصول على استثناءات كاملة من المكدسة ، وحصلت على الحل التالي.

    edt_amnt_sent.addTextChangedListener(new TextWatcher() {    
        @Override
        public void afterTextChanged(Editable s) {

            if (skipOnChange)
                return;

            skipOnChange = true;
            try {
                //method
                }
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                skipOnChange = false;
            }
        }
    });

    edt_amnt_receive.addTextChangedListener(new TextWatcher() {


        @Override
        public void afterTextChanged(Editable s) {

            if (skipOnChange)
                return;

            skipOnChange = true;
            try 
            {
                //method
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                skipOnChange = false;
            }
        }
    });

تم الإعلان عنه في البداية skipOnChange = false؛


يمكنك أيضًا استخدام طريقة hasFocus ():

public void onTextChanged(CharSequence s, int start,
     int before, int count) {
     if (Field2.hasfocus()){
         Field1.setText("");
     }
   }

اختبرت ذلك لمهمة الكلية التي كنت أعمل عليها لتحويل مقاييس درجات الحرارة كما كتبها المستخدم. عملت بشكل مثالي ، وهي طريقة أبسط.





onchange