10

I have a listview in my application that is basically a questionaire so there are some EditTexts that the user needs to fill. I've encountered the following issues:

  1. Some of the EditText require numeric input, so I set the inputType in the corresponding xml type as numeric, however, as when I click on the EditText the numeric keyboard is shown but almost immediately it disappears and the regular keyboard is shown.

  2. As you can imagine, I need to store the values that the user inputs in these EditTexts. The problem I have with this is that after I input some text in SOME EditTexts and I scroll down, the text is gone when I go back. You can see in my code that I made an attempt to prevent this and I should mention that it works perfectly fine with checkboxes.

  3. At the beginning I was having problems with losing the focus but I solved it looking at other questions (added descendantFocusablity="beforeDescendants" to the ListView and windowSoftInputMode="adjustPan"). Works fine except that when an EditText is below the half of the screen it loses focus as soon as I start typing into it. getView method for list adapter:

    public View getView(final int position,View result,ViewGroup parent)
    {
    final ViewHolder vh;
    final Question question = values.get(position);
    if(holders[position]==null)
        vh = new ViewHolder();
    else
        vh = holders[position];
    
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if(question.getQuestionType().equals(Question.TYPE_CLOSED))
    {
        result = inflater.inflate(R.layout.closed_question_list_item, null);
        vh.cb  = (CheckBox)result.findViewById(R.id.checkbox);
        vh.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() 
        {
    
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
            {
                vh.isChecked      = isChecked;
                holders[position] = vh;
            }
        });
        vh.cb.setChecked(vh.isChecked);
    }
    
    else
    {
        result = inflater.inflate(R.layout.numeric_question_list_item, null);
        vh.et  = (EditText)result.findViewById(R.id.question_et);
        vh.et.addTextChangedListener(new TextWatcher()
        {
            @Override
            public void afterTextChanged(Editable s) 
            {
                vh.tvValue = s.toString();
                holders[position] = vh;
                Log.i(TAG,"Entered afterTextChanged for "+ question.getText());
            }
    
            @Override
            public void beforeTextChanged(CharSequence s, int start,int count, int after) 
            {   
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start,int before, int count) 
            {
            }
        });
        vh.et.setText(vh.tvValue);
    }
    vh.tv = (TextView)result.findViewById(R.id.question_text);
    
    vh.tv.setText(question.getText());
    
    holders[position] = vh;
    result.setTag(vh);
    return result;
    }
    
user2535545
  • 161
  • 1
  • 1
  • 5

5 Answers5

19

Solutions to issue #3:

  1. Set descendantFocusablity="beforeDescendants" in the listview.

  2. Set windowSoftInputMode="adjustPan" in the manifest

  3. Set listview.setItemsCanFocus(true)

desidigitalnomad
  • 1,443
  • 21
  • 33
  • 1
    Thanks. 1. android:descendantFocusability="afterDescendants". 2. Write a saving of entered text like here: http://stackoverflow.com/a/19487574/2914140 or here: http://stackoverflow.com/a/21404201/2914140. – CoolMind Aug 30 '16 at 21:24
  • Works Well. Thanks :) – iffu Aug 30 '19 at 07:05
4

To expand on aaRBiyecH's answer above, here is a solution and a more in-depth explanation to your questions #1 and #3 (source):

You need to set the DescendantFocusability property of your ListView to "afterDescendants".

You can do this in the XML like this:

android:descendantFocusability="afterDescendants"

or in code like this:

listview.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS)

You also need to set the items to be focusable.

You can do this in the code like this: listview.setItemsCanFocus(true);

Also, you need to specify what is happening to the main window of your activity when the soft keyboard is shown. This is done by changing the WindowSoftInputMode attribute. You probably want to set it to AdjustPan so that your listview is not resized and thus GetView isn't called again. This is probably what is happening now when you hide the keyboard, GetView is called again and reset the original value in the EditText.

You can do this using the attribute android:windowSoftInputMode="adjustPan" on your main activity class's XML, or getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_PAN) programmatically.

Community
  • 1
  • 1
matt
  • 688
  • 7
  • 15
0

due to question 2 you can relate to this post EditText items in a scrolling list lose their changes when scrolled off the screen so there seems there s no easy solution to persist the edittexts when you scroll down

Yes your right you can try

EditText loses content on scroll in ListView

or just relate to the related posts on the right

Community
  • 1
  • 1
  • 1
    Thank you, but all the answer does is tell you to recycle the rows yourself but it doesn't explain how to do it effectively which is what I want to know. Would you happen to know where I can find something like that? – user2535545 Jun 30 '13 at 00:35
  • http://stackoverflow.com/questions/8772714/edittext-loses-content-on-scroll-in-listview?rq=1 –  Jun 30 '13 at 00:49
  • Thank you, I'll take a look at it. Anyhow, I managed to solve it, turns out using the vh local variable and the holders array was kind of redundant so I tried removing all that redundance and it worked just fine. – user2535545 Jun 30 '13 at 01:01
0

Its working for me.... Please check this

listview.setItemsCanFocus(true);
Karthik Kompelli
  • 2,104
  • 1
  • 19
  • 22
0

I have a listview with Edittext and when I input text in it, if before this, I scroll the listview, the adapter take some positions, not the selected.

My adapter take various positions instead of my selection:

etCantidad.addTextChangedListener(new TextWatcher() {
     @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) {
         String cantidadTMP = etCantidad.getText().toString();
         int cantidad;
         try {
              cantidad = Integer.parseInt(cantidadTMP);
              item.setCantidad(cantidad);
              Log.i("Name",""+item.getNombre());
             }catch (Exception e){
                    cantidad = 0;
             }
         Log.i("QuantityArrayAdapter",String.valueOf(cantidad));
     }});

One Editext selection:

09-25 09:22:10.458 12719-12719/? I/QuantityArrayAdapter: 1
09-25 09:22:10.458 12719-12719/? I/QuantityArrayAdapter: 1
09-25 09:22:10.458 12719-12719/? I/QuantityArrayAdapter: 1

So, I added this method in to the onTouchListener to only gets the selection position:

etCantidad.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            etCantidad.addTextChangedListener(new TextWatcher() {
                @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) {
                    String cantidadTMP = etCantidad.getText().toString();
                    int cantidad;
                    try {
                        cantidad = Integer.parseInt(cantidadTMP);
                        item.setCantidad(cantidad);
                        Log.i("Name",""+item.getNombre());
                    }catch (Exception e){
                        cantidad = 0;
                    }
                    Log.i("QuantityArrayAdapter",String.valueOf(cantidad));
                }
            });
            return false;
        }
    });

And only take the item i want so, its works for me.