Edittext In the Adapter in Android, checkbox remember status solution (2), androidedittext

Source: Internet
Author: User

Edittext In the Adapter in Android, checkbox remember status solution (2), androidedittext


Edittext In the Adapter in Android, and checkbox remembers the status solution (1)

In the previous article, the checkbox in the adapter remembers the status and edittext editable. Next we will talk about how to remember the content in edittext and how to ensure that the buttons are added and subtracted during the operation, the edittext object of the operation is not misplaced.

1. Remember the content in edittext

The solution is similar to checkbox, but there are still some differences. There are only two States in checkbox, while the value of edittext is not fixed. Checkbox we use an enum type list to save the status, so edittext won't work. We can use map and entity classes. I used hashMap for convenience.

// Listprivate List <Map <String, String> mData = new ArrayList <Map <String, String> ();
Simulate data during initialization

for (CartBean cartBean : list) {mData.add(new HashMap<String, String>());}

Edittext listening, and there is a log

            mHolder.num.addTextChangedListener(new TextWatcher() {@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {}@Overridepublic void afterTextChanged(Editable s) {if (!TextUtils.isEmpty(s.toString())) {                                     if(!TextUtils.isEmpty(s.toString())){mData.get(position).put(etValue,s.toString()); <strong>Log.i("afterTextChanged", "position"+position);</strong>}}}});
Obtains the value of edittext based on the position of the list.

       String value = mData.get(position).get(etValue);if (!TextUtils.isEmpty(value)) {mHolder.num.setText(value);} else {mHolder.num.setText("1");}
The code is out, and then you can find that there will still be confusion during the test. Later, after sliding the list multiple times back and forth, move the list to make the first one exactly come out, the next one comes in. At this time, the first item will be reused by the new item. The log should be like this when executing the above value assignment code.

01-27 15:55:46.612: I/afterTextChanged(4784): position001-27 15:55:46.622: I/afterTextChanged(4784): position101-27 15:55:46.632: I/afterTextChanged(4784): position201-27 15:55:46.642: I/afterTextChanged(4784): position301-27 15:55:46.642: D/AbsListView(4784): unregisterIRListener() is called 01-27 15:55:46.642: D/AbsListView(4784): unregisterIRListener() is called 01-27 15:55:46.662: D/AbsListView(4784): unregisterIRListener() is called 01-27 15:55:46.682: D/AbsListView(4784): unregisterIRListener() is called <strong>01-27 15:55:56.882: I/afterTextChanged(4784): position4</strong>
Only one listener is triggered for one operation.

The result is as follows:

01-27 15:53:43.772: I/afterTextChanged(4784): position001-27 15:53:43.772: I/afterTextChanged(4784): position501-27 15:53:43.772: I/afterTextChanged(4784): position501-27 15:53:43.772: I/afterTextChanged(4784): position901-27 15:53:43.772: I/afterTextChanged(4784): position501-27 15:53:43.772: I/afterTextChanged(4784): position001-27 15:53:43.772: I/afterTextChanged(4784): position601-27 15:53:43.772: I/afterTextChanged(4784): position1501-27 15:53:43.772: I/afterTextChanged(4784): position1501-27 15:53:43.772: I/afterTextChanged(4784): position1101-27 15:53:43.772: I/afterTextChanged(4784): position601-27 15:53:43.772: I/afterTextChanged(4784): position201-27 15:53:43.772: I/afterTextChanged(4784): position801-27 15:53:43.772: I/afterTextChanged(4784): position1201-27 15:53:43.772: I/afterTextChanged(4784): position1801-27 15:53:43.772: I/afterTextChanged(4784): position1301-27 15:53:43.772: I/afterTextChanged(4784): position901-27 15:53:43.772: I/afterTextChanged(4784): position401-27 15:53:43.772: I/afterTextChanged(4784): position4
An operation triggers many listeners and triggers multiple listeners, which will inevitably lead to the change of edittext values in multiple places. Later, I thought it was possible to execute it repeatedly on the adapter.

  mHolder.num.addTextChangedListener(new TextWatcher()
In order to prove my idea, I clicked in and checked the source code of the listener and found

 public void addTextChangedListener(TextWatcher watcher) {        if (mListeners == null) {            <strong>mListeners = new ArrayList<TextWatcher>();</strong>        }        mListeners.add(watcher);    }
It turns out that android uses arraylist to store all added listeners, so there is an operation that triggers multiple listeners. The checkbox does not appear because the listener object is reset every time.

 public void setOnClickListener(OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        <strong>getListenerInfo().mOnClickListener = l;</strong>    }
Sure enough, a new one is reset every time. In fact, we can see the purpose of the method based on the method name. One is add and the other is set.
The problem can be solved. In fact, the number of viewholder objects in the adapter is fixed and will only be reused when there are many objects. Therefore, we can set the same number of listeners as viewholder, you can do this.

if (convertView == null) {      ....      class MyTextWatcher implements TextWatcher {public MyTextWatcher() {}       @Overridepublic void onTextChanged(CharSequence s, int start,int before, int count) {}       @Overridepublic void beforeTextChanged(CharSequence s, int start,int count, int after) {}@Overridepublic void afterTextChanged(Editable s) {if (!TextUtils.isEmpty(s.toString())) {mData.get(position).put(etValue, s.toString()); //Log.i("afterTextChanged", "position" + position);}       }}mHolder.num.addTextChangedListener(new MyTextWatcher(mHolder));}
In this way, only the listener is added when convertview is null. This ensures that only one listener is available for an edittext file. Try again and find that it is still incorrect. The changed values cannot be saved. If something goes wrong, check the log.

01-27 16:59:40.512: I/afterTextChanged(12344): position001-27 16:59:40.532: I/afterTextChanged(12344): position101-27 16:59:40.542: I/afterTextChanged(12344): position201-27 16:59:40.552: I/afterTextChanged(12344): position301-27 16:59:42.772: I/afterTextChanged(12344): position401-27 16:59:43.712: I/afterTextChanged(12344): position001-27 16:59:44.502: I/afterTextChanged(12344): position101-27 16:59:45.392: I/afterTextChanged(12344): position201-27 16:59:46.632: I/afterTextChanged(12344): position301-27 16:59:47.492: I/afterTextChanged(12344): position401-27 16:59:47.842: I/afterTextChanged(12344): position001-27 16:59:49.142: I/afterTextChanged(12344): position101-27 16:59:51.662: I/afterTextChanged(12344): position201-27 16:59:52.822: I/afterTextChanged(12344): position301-27 16:59:53.192: I/afterTextChanged(12344): position401-27 17:00:06.662: I/afterTextChanged(12344): position0
The position value in the listener is 0-4. That is to say, no matter how the list slides, the position value is initialized only when convertview is empty. In this way, when the first item gets out of the screen and the next item enters the screen, the code is executed.

// At this time, the position of the Code must be greater than 4. Suppose it is 5, but the position of 5 in mData is null, this results in the first and 6th items being set to 1 String value = mData. get (position ). get (etValue); if (! TextUtils. isEmpty (value) {mHolder. num. setText (value);} else {mHolder. num. setText ("1 ");}
To solve this problem, you must dynamically obtain the position value in the listener callback method. Here we can do this

If (convertView = null ){...... class MyTextWatcher implements TextWatcher {public MyTextWatcher (ViewHolder holder) {mHolder = holder;}/*** in fact, viewholder with one screen cached, that is to say, a screen can display 10 pieces of data, so there will be 10 viewholder * in the memory. This function is to get the corresponding position through the edittext tag, value used to store edittext */private ViewHolder mHolder; @ Overridepublic void onTextChanged (CharSequence s, int start, int before, int count) {}@ Overridepublic void beforeTextC Hanged (CharSequence s, int start, int count, int after) {}@ Overridepublic void afterTextChanged (Editable s) {if (! TextUtils. isEmpty (s. toString () {// use a tag to obtain the position <strong> int position = (Integer) mHolder. num. getTag (); </strong> mData. get (position ). put (etValue, s. toString (); // Log. I ("afterTextChanged", "position" + position) ;}} mHolder. num. addTextChangedListener (new MyTextWatcher (mHolder); convertView. setTag (mHolder);} else {mHolder = (ViewHolder) convertView. getTag ();} // dynamically update the edittext tag <strong> mHolder. num. setTag (position); </strong>
Although viewholder is fixed, we can use the edittext tag to dynamically update the position value.

Then the test will show that edittext can remember the content.

2. Ensure that the edittext object operated is not misplaced when the plus or minus buttons are operated.

This is the case for normal listening.

mHolder.add.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {strNum = mData.get(position).get(etValue);int intnum = Integer.parseInt(strNum);intnum++;mHolder.num.setText("" + intnum);}});
But writing it in the adapter won't work, When the callback is triggered, edittext is not the one when the add button registers the listener, but the edittext In the last loaded item. The edittext object has changed, which is the root cause of the operation of edittext dislocation.I have already mentioned the solution to this problem in the previous article, that is, to save edittext. I will not post the code. Below I will post the demo link. If you are interested, please download it. If you have any good suggestions, share them with us and learn together.

Click to download the Demo


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.