How to remove all listeners added with addTextChangedListener

前端 未结 11 1572
谎友^
谎友^ 2020-11-27 16:24

I have a ListView where each row has an EditText control. I want to add a TextChangedListener to each row; one that contains extra dat

相关标签:
11条回答
  • 2020-11-27 17:01

    Save the current textwatcher in viewholder and you can find the one you want to remove.

    0 讨论(0)
  • 2020-11-27 17:01

    I had the same problem with xamarin/C# and I wrote for this a class to manage click events inside a ListView where the item view will be "recycled":

     public class ViewOnClickEventHandler: Java.Lang.Object
     {
        private List<EventHandler> EventList { get; set; }
    
        public void SetOnClickEventHandler(View view, EventHandler eventHandler)
        {
            if (view.Tag != null)
            {
                ViewOnClickEventHandler holder = ((ViewOnClickEventHandler)view.Tag);
    
                foreach (EventHandler evH in holder.EventList)
                    view.Click -= evH;
    
                for (int i = 0; i < holder.EventList.Count; i++)
                    holder.EventList[i] = null;
    
                holder.EventList.Clear();
            }
    
            EventList = new List<EventHandler>();
            EventList.Add(eventHandler);
            view.Click += eventHandler;
            view.Tag = this;
        }
    }
    

    You can use it in your ListView BaseAdapter GetItem method this way:

           TextView myTextView = convertView.FindViewById<TextView>(Resource.Id.myTextView);
    
            ViewOnClickEventHandler onClick = new ViewOnClickEventHandler();
            onClick.SetOnClickEventHandler(myTextView, new EventHandler(delegate (object sender, EventArgs e)
            {
                // Do whatever you want with the click event
            }));
    

    The ViewOnClickEventHandler class will care about multiple events on your textview. You can also change the class for textchange events. It's the same princip. I hope this will help.

    bye, nxexo007

    0 讨论(0)
  • 2020-11-27 17:05

    I also spent a lot of time finding the solution and finally ended up solving with the help of tag like below. It would remove previous TextWatcher instances by getting references from tag of the convertView. It perfectly solves the problem. In your CustomAdapter file, set a new inner class like below:

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

    Then in your overrided public View getView(int position, View convertView, ViewGroup parent) method implement the logic like below:

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

    Then implement TextWatcher class as below:

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

    It would remove previous TextWatcher instances by getting references from tag of the convertView

    0 讨论(0)
  • 2020-11-27 17:07

    You can remove TextWatcher from your EditText. First of all I suggest you to move TextWatcher declaration outside the the editText.addTextChangedListener(...):

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

    After that you will be able to set TextWather little bit simpler:

    editText.addTextChangedListener(yourTextWatcher);
    

    Than you can remove TextWatcher like this:

    editText.removeTextChangedListener(yourTextWatcher);
    

    and set another if you want.

    0 讨论(0)
  • 2020-11-27 17:11

    As you can see here: CodeSearch of TextView there is no way of removing all listeners. The only way is to provide the watcher you used to register it.

    I do not yet fully understand why there are other listeners already registered. However you can subclass the EditText, override the addTextChangedListener(..) and in it keep a copy of all added references yourself and then delegate to the superclass implementation. You then can also provide an additional method that removes all listeners.

    Get in touch if you need further explanations.

    0 讨论(0)
提交回复
热议问题