Metin Değiştirme Dinleyici Android


265

İki alanın olduğu bir durumum var. field1ve field2. Yapmak istediğim boş field2zaman field1tersi değişti ve kapanır. Sonunda sadece bir alanın üzerinde içerik var.

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

Ben takmak eğer cezayı çalışır addTextChangedListeneriçin field1sadece, ama her iki alana yönelik yaptığımda uygulama çöker. Belli ki birbirlerini süresiz değiştirmeye çalıştıkları için. field1Değişiklikler bir kez field2bu anda field2temizlenir field1ve böylece değişecektir ...

Birisi herhangi bir çözüm önerebilir mi?


yeni kullanıcılara, gözlemlenebilir bir dize alanı kullanarak iki yönlü veri bağlama için gidin, burada sağlanan tüm çözüm starting waiting blocking gc allocbu tür bir hata üretebilir , bu da çökmeye ve asılmaya neden olabilir. şimdi güvenli ve google tarafından tavsiye ..
Maifee Ul Asad

Yanıtlar:


460

Yalnızca alandaki metin boş olmadığında (yani uzunluk 0'dan farklı olduğunda) temizlemek için bir onay ekleyebilirsiniz.

field1.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @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(s.length() != 0)
        field2.setText("");
   }
  });

field2.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @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(s.length() != 0)
         field1.setText("");
   }
  });

TextWatcher Buraya ait belgeler .

Ayrıca lütfen adlandırma kurallarına saygı gösterin .


1
Tüm alan değiştikten sonra nasıl algılanır, çünkü herhangi bir düğmeye basıldığında her değiştiğinde algılar.
Rafael Guimarães

20

Bunun eski olduğunu biliyorum ama birisi bir gün buna tekrar gelebilir.

Ben bir EditText setText çağırmak ve ben istemiyordu onTextChanged benzer bir sorun vardı. İlk çözümüm dinleyici tarafından yapılan hasarı geri almak için setText () 'i çağırdıktan sonra kod yazmaktı. Ama bu çok zarif değildi. Biraz araştırma ve test yaptıktan sonra getText (). Clear () kullanmanın metni setText ("") ile aynı şekilde temizlediğini keşfettim, ancak metni ayarlamadığı için dinleyicinin çağrılmadığı, sorunumu çözdü. GetText (). Clear () için tüm setText ("") çağrıları değiştirdim ve artık bandajlara ihtiyacım yoktu, bu yüzden belki de sorununuzu çözecektir.

Bunu dene:

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

11

Android geliştirme için Kotlin TextChangedListener()kullanıyorsanız, bu kodu kullanarak ekleyebilirsiniz :

myTextField.addTextChangedListener(object : TextWatcher{
        override fun afterTextChanged(s: Editable?) {}

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })

5

Bir cevap biraz geç, ama işte yeniden kullanılabilir bir çözüm:

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

Yukarıdakiler kullanıldığında, setText()TextWatcher içinde gerçekleşen çağrılar, TextWatcher'ın tekrar çağrılmasına neden olmaz:

/**
 * 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) {
    }
}

5

Aynı sorunla karşılaştım ve stackOverflowistisnalar almaya devam ettim ve aşağıdaki çözümle geliyorum.

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

başlangıçta boole bildirildi skipOnChange = false;


1
"stack full" Sanırım Stack Overflow;)
Bir Droid

4

Ayrıca hasFocus () yöntemini de kullanabilirsiniz:

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

Bunu, kullanıcı yazarken sıcaklık ölçeklerini dönüştürmek için üzerinde çalıştığım bir üniversite ödevi için test edildi. Mükemmel çalıştı ve çok daha basit.


1
Kullanıcı içine girdiğinde editText.setText ne olacak? EditText bu durumda odaklanmıştır
Evgenii Vorobei

en iyi çözüm.
Syed Hissaan

3

Başka bir değeri EditTextboş olarak ayarlamadan önce Dize'yi kontrol edin . eğer Field1ihtiyacı ( "") tekrar geçmek için neden o zaman boş? Böylece Dizenizin boyutunu s.lenght () veya başka bir çözümle kontrol edebilirsiniz.

Dize uzunluğunu kontrol etmenin başka bir yolu:

String sUsername = Field1.getText().toString();
if (!sUsername.matches(""))
{
// do your job
}

2

Bunun için kendi uzantımı yazdım, bana çok yardımcı oldu. (Kotlin)

Sadece şöyle yazabilirsiniz:

editText.customAfterTextChanged { editable -> 
    //You have accessed the editable object. 
}

Uzantım:

fun EditText.customAfterTextChanged(action: (Editable?)-> Unit){
    this.addTextChangedListener(object : TextWatcher {
       override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
       override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
       override fun afterTextChanged(editable: Editable?) {
        action(editable)
    }
})}

2
editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (noteid != -1) {
                    MainActivity.notes.set(noteid, String.valueOf(charSequence));
                    MainActivity.arrayAdapter.notifyDataSetChanged();
                }
            }
            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

Bu kodda noteid temel olarak girintiye konan veya girintiden geçen argümanlardır.

  Intent intent = getIntent();
         noteid = intent.getIntExtra("noteid", -1);

daha açık bir şekilde anlamak istiyorsanız, dezavantajlı kod temel olarak ekstra koddur.

how to make the menu or insert the menu in our code , 
    create the  menu folder this the folder created by going into the raw
    ->rightclick->
    directory->name the folder as you wish->
    then click on the directory formed->
    then click on new file and then name for file as you wish ie the folder name file
    and now type the 2 lines code in it and see the magic.

düzenleme amacıyla NoteEditor.java olarak adlandırılan yeni etkinlik kodu, benim app temel not uygulamasıdır.

package com.example.elavi.notes;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.Toast;

import static android.media.CamcorderProfile.get;
public class NoteEditorActivity extends AppCompatActivity {
    EditText editText;
    int noteid;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_note_editor);
        editText = findViewById(R.id.editText);
        Intent intent = getIntent();
         noteid = intent.getIntExtra("noteid", -1);
        if (noteid != -1) {
            String text = MainActivity.notes.get(noteid);
            editText.setText(text);

           Toast.makeText(getApplicationContext(),"The arraylist content is"+MainActivity.notes.get(noteid),Toast.LENGTH_SHORT).show();
        }
        else
        {
            Toast.makeText(getApplicationContext(),"Here we go",Toast.LENGTH_SHORT).show();
            MainActivity.notes.add("");
            noteid=MainActivity.notes.size()-1;
        }
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (noteid != -1) {
                    MainActivity.notes.set(noteid, String.valueOf(charSequence));
                    MainActivity.arrayAdapter.notifyDataSetChanged();
                }
            }
            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }
}

1

In KOTLIN sadece kullanım ktx uzatma işlevi: (O kullanır TextWatcher)

yourEditText.doOnTextChanged { text, start, count, after -> 
        // action which will be invoked when the text is changing
    }


içe aktar core-KTX:

implementation "androidx.core:core-ktx:1.2.0"

1

Bir alan için TextWatcher'ı metnini düzenlemeden hemen önce kaldırabilir ve ardından metni düzenledikten sonra tekrar ekleyebiliriz.

Field1 ve field2 için Text Watchers'ı, onlara bir ad vermek üzere ayrı değişkenler olarak bildirin : örneğin, field1 için

private TextWatcher Field_1_Watcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void afterTextChanged(Editable s) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

};

: o zaman adını kullanarak Gözetmenin eklemek field1.addTextChangedListener(Field_1_Watcher)için field1 ve field2.addTextChangedListener(Field_2_Watcher)için alan2

Değiştirmeden önce field2 metin TextWatcher kaldırın: field2.removeTextChangedListener(Field_2_Watcher) metni değiştirmek: field2.setText("")

ardından TextWatcher'ı geri ekleyin: field2.addTextChangedListener(Field_2_Watcher)

Diğer alan için de aynısını yapın


-3

onCreateYöntemde arka planı dinamik olarak ekleyin :

getWindow().setBackgroundDrawableResource(R.drawable.background);

XML'den arka planı da kaldır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.