EditText inside ListView will not stay focused

30,111

Solution 1

EditTexts within ListViews are extremely tricky. I'd suggest you avoid them like the plague if possible. When I was messing with them, this answer was helpful though. If you only have a few items you can always just use a ScrollView.

Solution 2

If you want list items to take focus, its pretty straight forward: Make the listview not focusable, and say that its focus is afterDescendants which lets EditTexts and other focusable items take focus.

<ListView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="afterDescendants"
    android:focusable="false" />

Solution 3

I know this question is old, but I was also fighting with EditText and ListView today. I think lose time with focus problem or updating dataset is the end of the line.

So, I created an Activity and dynamically added the controls I need. In this example I added two controls: a textview and edittext.

First I create a class to be a "container" of the controls and them I put the controls on a ScrollView.

The layout.xml file:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llMain"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tvHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <ScrollView
        android:id="@+id/svMain"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/llForm"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >

        </LinearLayout>
    </ScrollView>

</LinearLayout>

The "containter" class:

import android.widget.EditText;

public class RespostasArray {

    private int pergunta;
    private int formulario;
    private int form_coord;
    private int coordenada;
    private int form_resposta;
    private String questao;
    private String resposta;
    private EditText respostaEdit;

    public RespostasArray() {
        respostaEdit = null;
    }

    public int getPergunta() {
        return pergunta;
    }

    public void setPergunta(int pergunta) {
        this.pergunta = pergunta;
    }

    public int getFormulario() {
        return formulario;
    }

    public void setFormulario(int formulario) {
        this.formulario = formulario;
    }

    public int getForm_coord() {
        return form_coord;
    }

    public void setForm_coord(int form_coord) {
        this.form_coord = form_coord;
    }

    public int getCoordenada() {
        return coordenada;
    }

    public void setCoordenada(int coordenada) {
        this.coordenada = coordenada;
    }

    public int getForm_resposta() {
        return form_resposta;
    }

    public void setForm_resposta(int form_resposta) {
        this.form_resposta = form_resposta;
    }

    public String getQuestao() {
        return questao;
    }

    public void setQuestao(String questao) {
        this.questao = questao;
    }

    public String getResposta() {
        return resposta;
    }

    public void setResposta(String resposta) {
        this.resposta = resposta;
    }

    public EditText getRespostaEdit() {
        return respostaEdit;
    }

    public void setRespostaEdit(EditText respostaEdit) {
        this.respostaEdit = respostaEdit;
    }

}

So, the main activity:

    import java.util.ArrayList;
    import java.util.List;

    import jv.android.getpoint.R;
    import jv.android.getpointlib.data.Formularios;
    import jv.android.getpointlib.data.GetPointDataHelper;
    import jv.android.getpointlib.data.Respostas;
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.view.WindowManager.LayoutParams;
    import android.widget.EditText;
    import android.widget.LinearLayout;
    import android.widget.TextView;

    public class RespostasActivity extends Activity {

        private Intent intent;
        private ArrayList<RespostasArray> listItems = null;
        private GetPointDataHelper db = null;
        private int coordenada = -1;
        private int formulario = -1;
        private LinearLayout llRespostas;
        private TextView tvRespostasHeader;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout.xml);

            llRespostas = (LinearLayout)findViewById(R.id.llRespostas);
            tvHeader = (TextView)findViewById(R.id.tvHeader);

            listItems = new ArrayList<RespostasArray>();
            db = new GetPointDataHelper(this, false);

            intent = getIntent();

            if (intent != null)
            {
                Bundle params = intent.getExtras();

                if (params != null) {
                    coordenada = params.getInt("coordenada");
                    formulario = params.getInt("formulario");

                    tvHeader.setText("Some header");

// Load the fields I need from SQLite. Change it to your needs.
                    List<Respostas> respostas = db.selectAllRespostaDaCoordenada (coordenada, formulario);

                    if (respostas != null && respostas.size() > 0) {
                        for (int i = 0; i < respostas.size(); i++) {
                            TextView tv = new TextView(getApplicationContext());
                            tv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
                            tv.setText(respostas.get(i).getQuestao().trim() + (respostas.get(i).getQuestao().trim().endsWith(":") ? "" : ":"));
                            llRespostas.addView(tv);

                            EditText et = new EditText(getApplicationContext());
                            et.setText(respostas.get(i).getResposta().trim());
                            et.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));                      
                            llRespostas.addView(et);

                            RespostasArray ra = new RespostasArray();
                            ra.setCoordenada(respostas.get(i).getCoordenada());
                            ra.setForm_coord(respostas.get(i).getForm_coord());
                            ra.setForm_resposta(respostas.get(i).getForm_resposta());
                            ra.setFormulario(respostas.get(i).getFormulario());
                            ra.setPergunta(respostas.get(i).getPergunta());
                            ra.setQuestao(respostas.get(i).getQuestao());
                            ra.setResposta(respostas.get(i).getResposta());
                            ra.setRespostaEdit(et);                     

                            listItems.add(ra);                      
                        }
                    }
                }
            }               
        }

        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {    
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                doProcessResult();          
            }    

            return super.onKeyDown(keyCode, event);
        }

        private void doProcessResult() {
            for (int i = 0; i < listItems.size(); i++) {
                if (listItems.get(i).getForm_resposta() == 0) {
                    db.insertResposta(listItems.get(i).getFormulario(), listItems.get(i).getForm_coord(), listItems.get(i).getPergunta(), listItems.get(i).getRespostaEdit().getText().toString());
                } else {
                    db.updateResposta(listItems.get(i).getForm_resposta(), listItems.get(i).getRespostaEdit().getText().toString());                
                }
            }
        }
    }

I hope it helps someone.

Share:
30,111

Related videos on Youtube

Matt
Author by

Matt

Updated on September 14, 2020

Comments

  • Matt
    Matt over 3 years

    I have an EditText inside each row of a ListView. For some reason, when I tap the EditText, it briefly gains focus but then immediately loses it.

    I have tried these things:

    listView.setItemsCanFocus(true);
    editText.setFocusable(true);
    


    While the EditText is (briefly) focused, the Enter key says Next and the auto-correct bar is present. When it loses focus, the soft keyboard stays up, but the Enter key becomes a Return Arrow, and the auto-correct bar disappears.

    • njzk2
      njzk2 over 11 years
      i assume you forgot about how views are recycled. suggestion : don't use editText in list item.
    • Matt
      Matt over 11 years
      Why would recycling them matter for focus?
    • njzk2
      njzk2 over 11 years
      because there are very few edittext that are used alternatively for drawing each row, and they are receiving all kind of focus state change at the same time
    • Kasim Rangwala
      Kasim Rangwala over 7 years
      I've done this using android:windowSoftInputMode="adjustPan" inside <activity>. It's working like charm.
  • Matt
    Matt over 11 years
    Yeah, using a vertical linearlayout inside a scrollview did the trick. One thing I noticed is that if it is a ListActivity, the EditTexts in the ListView work fine. But not if it's a ListView in a regular activity.
  • Sharp Steel Software
    Sharp Steel Software almost 10 years
    If we avoid them, what is the replacement?
  • dmon
    dmon almost 10 years
    "You can always use a ScrollView"
  • SpaceMonkey
    SpaceMonkey almost 9 years
    doesn't seem to be working
  • karthik kolanji
    karthik kolanji over 8 years
    It worked for me ... thanks :)
  • Subho
    Subho over 8 years
    Thanks for your valuable answer :)
  • Ranjithkumar
    Ranjithkumar almost 8 years
    yes working for me also
  • Zafer
    Zafer about 6 years
    how is it possible to use ScrollView for dynamically created views?
  • bluetoothfx
    bluetoothfx over 5 years
    it is working....thanks :)
  • Miki
    Miki over 4 years
    Worked but not in all case. So this one be better in some case (without android:descendantFocusability): in activity: getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT‌​_INPUT_ADJUST_PAN); or in andoidmanifest.xml at activity part: android:windowSoftInputMode="adjustPan"