Gen*_*ari 52 android listview textwatcher android-edittext
我有一个ListView每行有EditText控件的地方.我想在TextChangedListener每一行添加一个; 一个包含额外数据的数据,它说明了哪一行EditText.问题是,当getView被调用时,TextWatchers会添加多个; 因为convertView已经有一个TextWatcher(和一个指向不同的行).
MyTextWatcher watcher = new MyTextWatcher(currentQuestion);
EditText text = (EditText)convertView.findViewById(R.id.responseText);
text.addTextChangedListener(watcher);
Run Code Online (Sandbox Code Playgroud)
MyTextWatcher是我的班级实施TextWatcher; 并处理文本事件.CurrentQuestion让我知道我正在采取哪一行.当我输入框中; TextWatcher调用多个实例.
有没有办法TextWatchers在添加新的之前删除它?我看到了removeTextChangedListener方法,但这需要TextWatcher传入一个特定的,我不知道如何获得指针TextWatcher已经存在的指针.
ina*_*ruk 42
EditText直接使用当前界面无法做到这一点.我看到两种可能的解决方案
TextWatcher添加到特定EditText实例的内容.EditText并增加清除所有观察者的可能性.以下是第二种方法的示例 - ExtendedEditText:
public class ExtendedEditText extends EditText
{
private ArrayList<TextWatcher> mListeners = null;
public ExtendedEditText(Context ctx)
{
super(ctx);
}
public ExtendedEditText(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
}
public ExtendedEditText(Context ctx, AttributeSet attrs, int defStyle)
{
super(ctx, attrs, defStyle);
}
@Override
public void addTextChangedListener(TextWatcher watcher)
{
if (mListeners == null)
{
mListeners = new ArrayList<TextWatcher>();
}
mListeners.add(watcher);
super.addTextChangedListener(watcher);
}
@Override
public void removeTextChangedListener(TextWatcher watcher)
{
if (mListeners != null)
{
int i = mListeners.indexOf(watcher);
if (i >= 0)
{
mListeners.remove(i);
}
}
super.removeTextChangedListener(watcher);
}
public void clearTextChangedListeners()
{
if(mListeners != null)
{
for(TextWatcher watcher : mListeners)
{
super.removeTextChangedListener(watcher);
}
mListeners.clear();
mListeners = null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是如何ExtendedEditText在xml布局中使用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ua.inazaruk.HelloWorld.ExtendedEditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="header"
android:gravity="center" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
Ant*_*nko 26
您可以从EditText中删除TextWatcher.首先,我建议你在editText.addTextChangedListener(...)之外移动TextWatcher声明:
protected TextWatcher yourTextWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
// your logic here
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// your logic here
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// your logic here
}
};
Run Code Online (Sandbox Code Playgroud)
之后,您将能够更简单地设置TextWather:
editText.addTextChangedListener(yourTextWatcher);
Run Code Online (Sandbox Code Playgroud)
你可以像这样删除TextWatcher:
editText.removeTextChangedListener(yourTextWatcher);
Run Code Online (Sandbox Code Playgroud)
并根据需要设置另一个.
gun*_*ngh 10
我也花了很多时间找到解决方案,最后在下面的标签的帮助下最终解决了.它将通过从convertView的标记获取引用来删除以前的TextWatcher实例.它完美地解决了这个问题.在CustomAdapter文件中,设置一个新的内部类,如下所示:
private static class ViewHolder {
private TextChangedListener textChangedListener;
private EditText productQuantity;
public EditText getProductQuantity() {
return productQuantity;
}
public TextChangedListener getTextChangedListener() {
return textChangedListener;
}
public void setTextChangedListener(TextChangedListener textChangedListener) {
this.textChangedListener = textChangedListener;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的覆盖公共视图中,getView(int position,View convertView,ViewGroup parent)方法实现如下逻辑:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
EditText productQuantity;
TextChangedListener textChangedListener;
if(convertView==null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.cart_offer_item, parent, false);
productQuantity=(EditText)convertView.findViewById(R.id.productQuantity);
addTextChangedListener(viewHolder, position);
convertView.setTag(viewHolder);
}
else
{
ViewHolder viewHolder=(ViewHolder)convertView.getTag();
productQuantity=viewHolder.getProductQuantity();
removeTextChangedListener(viewHolder);
addTextChangedListener(viewHolder, position);
}
return convertView;
}
private void removeTextChangedListener(ViewHolder viewHolder)
{
TextChangedListener textChangedListener=viewHolder.getTextChangedListener();
EditText productQuantity=viewHolder.getProductQuantity();
productQuantity.removeTextChangedListener(textChangedListener);
}
private void addTextChangedListener(ViewHolder viewHolder, int position)
{
TextChangedListener textChangedListener=new TextChangedListener(position);
EditText productQuantity=viewHolder.getProductQuantity();
productQuantity.addTextChangedListener(textChangedListener);
viewHolder.setTextChangedListener(textChangedListener);
}
Run Code Online (Sandbox Code Playgroud)
然后实现TextWatcher类,如下所示:
private class TextChangedListener implements TextWatcher
{
private int position;
TextChangedListener(int position)
{
this.position=position;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
Log.d("check", "text changed in EditText");
}
}
Run Code Online (Sandbox Code Playgroud)
它将通过从convertView的标记获取引用来删除以前的TextWatcher实例
这个问题已经问了很久了,但有人可能会发现这很有用。Recyclerview 中 TextWatcher 的问题是我们必须确保在视图回收之前将其删除。否则,我们会丢失 TextWatcher 的实例,并且在 OnBindViewHolder() 中调用removeTextChangedListener(textWatcher)只会删除 TextWatcher 的当前实例。
我解决这个问题的方法是将 TextChangedListener 添加到 FocusChangedListener 中:
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
editText.addTextChangedListener(textWatcher)
}
else{
editText.removeTextChangedListener(textWatcher)
}
}
});
Run Code Online (Sandbox Code Playgroud)
这样,我确信当 editText 没有焦点时,文本观察器就会被删除,并在获得焦点时再次添加。因此,当 recyclerview 被回收时,editText 将删除所有 textChangeListener。
将当前的textwatcher保存在viewholder中,您可以找到要删除的文本.
我在 RecyclerView 中的许多 EditText 中遇到了类似的问题。我通过反思解决了它。ReflectionTextWatcher.removeAll(your_edittext)在绑定视图之前调用。这段代码找到所有 TextWatchers 并将它们从本地 EditText 的名为“mListeners”的列表中删除。
public class ReflectionTextWatcher {
public static void removeAll(EditText editText) {
try {
Field field = findField("mListeners", editText.getClass());
if (field != null) {
field.setAccessible(true);
ArrayList<TextWatcher> list = (ArrayList<TextWatcher>) field.get(editText); //IllegalAccessException
if (list != null) {
list.clear();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static Field findField(String name, Class<?> type) {
for (Field declaredField : type.getDeclaredFields()) {
if (declaredField.getName().equals(name)) {
return declaredField;
}
}
if (type.getSuperclass() != null) {
return findField(name, type.getSuperclass());
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望,这会对某人有所帮助。
| 归档时间: |
|
| 查看次数: |
40690 次 |
| 最近记录: |