Android上的文本更改监听器

355

我有一个情况,有两个字段。field1field2。我想做的就是当field1被更改时清空field2,反之亦然。因此最终只有一个字段有内容。

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,以此类推......

有人能提出任何解决方案吗?


1
对于新用户而言,在进行双向数据绑定时,应当使用可观察字符串字段。所有在此处提供的解决方案都可能会产生“starting waiting blocking gc alloc”这种类型的错误,甚至可能导致崩溃和挂起。因此,请使用数据绑定,这是现在由谷歌推荐的安全方法。 - Maifee Ul Asad
19个回答

3

在清空另一个EditText之前,请先检查字符串。如果Field1为空,为什么还要再次更改为("")?因此,您可以使用s.length()或任何其他解决方案检查您的字符串的大小。

您可以检查字符串长度的另一种方法是:

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

1
etSearch.addTextChangedListener(object : TextWatcher {
     override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
          TODO("Not yet implemented")
     }

     override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
          TODO("Not yet implemented")
     }

     override fun afterTextChanged(p0: Editable?) {
          TODO("Not yet implemented")
     }
})

1
我们可以在编辑文本之前删除字段的TextWatcher,然后在编辑文本后将其添加回来。
field1field2声明不同的变量作为它们的Text Watcher名称:例如,对于field1
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) {

    }

};

然后使用其名称添加观察者: field1.addTextChangedListener(Field_1_Watcher),对于field1,以及 field2.addTextChangedListener(Field_2_Watcher),对于field2

在更改field2文本之前,请删除TextWatcher: field2.removeTextChangedListener(Field_2_Watcher) 更改文本: field2.setText("")

然后重新添加TextWatcher: field2.addTextChangedListener(Field_2_Watcher)

对另一个字段执行相同的操作


1

以下是可能有助于某些人的另一种解决方案。有两个EditText,在编辑后互相更改。默认情况下,这会导致循环。

使用变量:

Boolean uahEdited = false;
Boolean usdEdited = false;

添加 TextWatcher
uahEdit = findViewById(R.id.uahEdit);
usdEdit = findViewById(R.id.usdEdit);

uahEdit.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            if (!usdEdited) {
                uahEdited = true;
            }
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            String tmp = uahEdit.getText().toString();

            if(!tmp.isEmpty() && uahEdited) {
                uah = Double.valueOf(tmp);
                usd = uah / 27;
                usdEdit.setText(String.valueOf(usd));
            } else if (tmp.isEmpty()) {
                usdEdit.getText().clear();
            }
        }

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

usdEdit.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            if (!uahEdited) {
                usdEdited = true;
            }
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            String tmp = usdEdit.getText().toString();

            if (!tmp.isEmpty() && usdEdited) {
                usd = Double.valueOf(tmp);
                uah = usd * 27;
                uahEdit.setText(String.valueOf(uah));
            } else if (tmp.isEmpty()) {
                uahEdit.getText().clear();
            }
        }

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

不要过于批评。我是一名新手开发者。


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) {

            }
        });

在这段代码中,noteid 基本上是传递进入缩进或通过缩进传递的参数。
  Intent intent = getIntent();
         noteid = intent.getIntExtra("noteid", -1);

下面的代码基本上是额外的代码,如果你想更清楚地了解。
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.

新的活动代码名为NoteEditor.java,用于编辑目的,我的应用基本上是笔记应用程序。

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) {

            }
        });
    }
}

0

你可以使用这个
我提供了最新的textchangelistner方法

edMsg.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 (i2 == 0){
                    ////Edit text blanked
                } 
                
                String msg = charSequence.toString();/// your text on changed in edit text
                
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

0

这对我有用。

将引用添加到edittext,添加addtextchangedlistener方法。然后添加变量isEdit,它将帮助执行beforetextchagned、ontextchagned或aftertextchagned事件之一仅1次。在try块内,您可以实现您的逻辑或任何您需要的内容,甚至像我一样重新分配edittext的值。

numberFloat.addTextChangedListener(object : TextWatcher{
   private var isEdit:Boolean = false
   override fun beforeTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int){
       if(isEdit)
         return
       isEdit = true
       try {
          //tus condiciones, logica o evento
       }finally {
          isEdit = false
       }
   }
   override fun onTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int){
       if(isEdit)
         return
       isEdit = true
       try {
         //tus condiciones, logica, evento, reasignar nuevo valor al editText
         if(!text.isNullOrEmpty()){
             if(text.length > 3){
               println("es mayor a 3")
               numberFloat.setText("0")
             }
         }
       }finally {
          isEdit = false
       }
   }
   override fun afterTextChanged(text: Editable?) {
       if(isEdit)
         return
       isEdit = true
       try {
          //tus condiciones, logica o evento
       }finally {
          isEdit = false
       }
   }
})

0
如果你不想覆盖所有的方法。
fun EditText.afterTextChanged(afterTextChanged: (chars: Editable?) -> Unit = { _ -> }) {
    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            afterTextChanged(s)
        }

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

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

    })
}

fun EditText.beforeTextChanged(beforeTextChanged: (chars: CharSequence?, start: Int, count: Int, after: Int) -> Unit = { _, _, _, _ -> }) {
    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
        }

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

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

    })
}

fun EditText.onTextChanged(onTextChanged: (chars: CharSequence?, start: Int, count: Int, after: Int) -> Unit = { _, _, _, _ -> }) {
    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) {
            onTextChanged(s, start, before, count)
        }

    })
}

-4
onCreate方法中动态添加背景:
getWindow().setBackgroundDrawableResource(R.drawable.background);

同时从XML中移除背景。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接