Android Focusable EditText inside ListView


Hi,

I was trying to implement something from here. But I don’t understand what he is doing. Using this works well to get focus on EditText.

The main issue I face later, when I have lots of item in ListView. I found this answer very helpful to understand recycling view. You can’t save anything on ListView Item. You must need to handle another data-source that maintain your changes in ListView’s item. Not talking too much, I’m just presenting working example, so readers can understand quickly.

main.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">
	<ListView android:id="@+id/MyList" android:layout_height="fill_parent"
		android:layout_width="fill_parent" android:descendantFocusability="beforeDescendants">
	</ListView>
</LinearLayout>

item.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">

	<EditText android:id="@+id/ItemCaption"
		android:layout_height="wrap_content" android:layout_width="fill_parent"
		android:layout_marginLeft="2dip" android:singleLine="true">
	</EditText>

</LinearLayout>

AndroidCustomListViewActivity.java

package com.isummation.android;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;

public class AndroidCustomListViewActivity extends Activity {
	private ListView myList;
	private MyAdapter myAdapter;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		myList = (ListView) findViewById(R.id.MyList);
		myList.setItemsCanFocus(true);
		myAdapter = new MyAdapter();
		myList.setAdapter(myAdapter);

	}

	public class MyAdapter extends BaseAdapter {
		private LayoutInflater mInflater;
		public ArrayList myItems = new ArrayList();

		public MyAdapter() {
			mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			for (int i = 0; i < 20; i++) {
				ListItem listItem = new ListItem();
				listItem.caption = "Caption" + i;
				myItems.add(listItem);
			}
			notifyDataSetChanged();
		}

		public int getCount() {
			return myItems.size();
		}

		public Object getItem(int position) {
			return position;
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = mInflater.inflate(R.layout.item, null);
				holder.caption = (EditText) convertView
						.findViewById(R.id.ItemCaption);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}
			//Fill EditText with the value you have in data source
			holder.caption.setText(myItems.get(position).caption);
			holder.caption.setId(position);

			//we need to update adapter once we finish with editing
			holder.caption.setOnFocusChangeListener(new OnFocusChangeListener() {
				public void onFocusChange(View v, boolean hasFocus) {
					if (!hasFocus){
						final int position = v.getId();
						final EditText Caption = (EditText) v;
						myItems.get(position).caption = Caption.getText().toString();
					}
				}
			});

			return convertView;
		}
	}

	class ViewHolder {
		EditText caption;
	}

	class ListItem {
		String caption;
	}
}

79 thoughts on “Android Focusable EditText inside ListView

  1. This is what I was looking for. I tried to copy the code and make it a working sample. But I am getting few problems. Firstly myItems.get(position) is not type casted before using .caption. I type casted it to ListItem.

    The code then worked. But When I click on any of the list item edittext, the focus moves out immediately and I am not able to type anything. However the keyboard is still on. But what ever i type in does not appear as the focus is lost.

      1. Playing with this I can add the following :

        If you try to add you ListView into a TabActivity you also have to set android:windowSoftInputMode=”adjustPan” for the TabActivity definition in the manifest.

    1. Dear Vikas / Vinod,

      Can you please tell me how to type cast the :

      1. holder.caption.setText(myItems.get(position).caption);

      2. myItems.get(position).caption = Caption.getText().toString();

      because both of this line I am getting error. Can you please tell me it is very urgent.

      1. 1. myItems.get(position).caption

        Here caption is a string

        2. Caption.getText().toString()

        Here it is an EditText

        Now you don’t need to type cast.
        My be your object is not having Caption as a string.

        Sorry for late reply..

      2. You need to change

        public ArrayList myItems = new ArrayList();

        for

        public ArrayList myItems = new ArrayList();

      3. To solve the above problem simply replace

        public ArrayList myItems = new ArrayList(); // at line 35

        with

        public ArrayList myItems = new ArrayList();

      4. Sorry!!!!!

        To solve the above problem simply replace

        public ArrayList myItems = new ArrayList(); // at line 35

        with

        public ArrayList myItems = new ArrayList();

      5. can you please post the answer if you have it….It give me cannot resolve caption error

  2. Thank you very much Vikas. This helped me a lot. Is there any side effects of using a edit text in listview that i need to be aware of?

      1. Hi Vikas. I found that out of the 20 rows in the list view i can edit till 14. After that I cannot scroll the listview up. That is because the end of the list view comes to the end of the screen. so no more scrolling is allowed. How ever the row above the keyboard is still the 14th. I am not able to edit the 15th to 20 row. But I cam come out of the keyboard and click on the 20th row and then start typing. The types value goes into the edit text, but I is behind the keyboard and cannot be seen. Is there a work around for this?

  3. Thank you. I was struggling for hours with this problem and forums were over crowded with different answers.

    1. Cheers! don’t use forums more. I also face this issue, and I stopped my fingers from touching mouse and keyboard, and started thinking!!! That is why I blog….

    2. Forums are good, but use it once you have our own code and implementation. because then and then you can have some materials to compare it with others. Then you can decide which is the best approach.
      Thanks for using my blog..

  4. Hi sir
    your example is good. present i face this type of problem .In my listview there is one text view and one edit text when i enter the data in edit text after i scroll up and down then that will be place some where .i post my code please help me very urgent .
    package Com.list;

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

    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ListView;
    import android.widget.TextView;

    public class MyList extends Activity
    {
    List<? extends Map> Data;
    TextView tvCategoryName ;
    Button next,previous;
    String menuType;
    String[] catName;
    ListView displaylist;
    // DataBase data;
    int i;
    public AgrisalesAdapter notes;
    ArrayList Agrisaleslist = new ArrayList();

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.agrisales1);
    //data=new DataBase(this);
    displaylist=(ListView)findViewById(R.id.l1);
    notes=new AgrisalesAdapter(this,R.layout.edittext, Agrisaleslist);
    displaylist.setAdapter(notes);
    Agrisaleslist.add(new Constructor(“Bayer”,””));
    Agrisaleslist.add(new Constructor(“Dupont”,””));
    Agrisaleslist.add(new Constructor(“Mallika”,””));
    Agrisaleslist.add(new Constructor(“Syngenta”,””));
    Agrisaleslist.add(new Constructor(“Tulasi”,””));
    Agrisaleslist.add(new Constructor(“Bharath”,””));
    Agrisaleslist.add(new Constructor(“Dowagro”,””));
    Agrisaleslist.add(new Constructor(“Prasd”,””));
    Agrisaleslist.add(new Constructor(“snadhya”,””));
    Agrisaleslist.add(new Constructor(“ramu”,””));
    /* data.open();
    data.insertTitle(1, “Bayer”, “”);
    data.insertTitle(1, “Dupont”, “”);
    data.insertTitle(1, “Syngenta”, “”);
    data.insertTitle(1, “Pioneer”, “”);
    data.insertTitle(1, “Mallika”, “”);
    data.insertTitle(1, “Bunny”, “”);
    data.insertTitle(1, “Tulasi”, “”);
    data.insertTitle(1, “Dov”, “”);

    Cursor AgriCursor= data.getlistitems();
    if(AgriCursor.moveToFirst())
    {
    do {
    int id=AgriCursor.getInt(0);
    System.out.println(“id:::::::::”+id);
    String itemname1=AgriCursor.getString(1);
    String itemcal=AgriCursor.getString(2);
    Agrisaleslist.add(new Constructor(itemname1,itemcal));
    notes.notifyDataSetChanged();
    } while (AgriCursor.moveToNext());
    }
    AgriCursor.close();
    data.close();*/

    }
    public class AgrisalesAdapter extends BaseAdapter{
    private Context context;
    private List buttonList;
    //private int rowResID;
    public AgrisalesAdapter(Context context, int rowResID,
    List buttonList ) {
    this.context = context;
    //this.rowResID = rowResID;
    this.buttonList = buttonList;
    }
    public int getCount() {
    return buttonList.size();
    }
    public Object getItem(int position) {
    return buttonList.get(position);
    }
    public long getItemId(int position) {
    return position;
    }
    public View getView(final int position, View convertView, ViewGroup parent) {

    final Constructor row = buttonList.get(position);
    ViewHolder holder;

    /* LayoutInflater inflater = LayoutInflater.from( context );
    View v = inflater.inflate( R.layout.edittext, parent, false );

    final TextView textTextControl1 = (TextView)v.findViewById( R.id.inputtypetext1 );
    final TextView quantitytext = (TextView)v.findViewById( R.id.totalturnoveredit1 );
    textTextControl1.setText(row.s());
    quantitytext.setText(row.Quantity());

    return v;*/

    if (convertView == null)
    {
    LayoutInflater minflater = LayoutInflater.from( context );
    convertView = minflater.inflate(R.layout.edittext, null);

    holder = new ViewHolder();
    holder.name = (TextView) convertView.findViewById(R.id.inputtypetext1);
    holder.edit = (EditText) convertView.findViewById(R.id.totalturnoveredit1 );
    holder.name.setTag(position);
    holder.edit.setTag(position);
    holder.name.setText(row.s());
    holder.edit.setText(row.Quantity());
    convertView.setTag(holder);
    }
    else
    {
    holder = (ViewHolder) convertView.getTag();

    convertView.setTag(holder);

    }

    return convertView;
    }

    }

    static class ViewHolder {
    TextView name;
    EditText edit;
    }
    }

    Constructor.java:-

    package Com.list;

    public class Constructor {
    private String t;
    Long rowid;
    String quantity;
    String calories;
    public Constructor(String s,String quantity)
    {

    this.t=s;
    this.quantity=quantity;

    }

    public String s ()
    {
    return t;
    }
    public String Quantity()
    {
    return quantity;
    }
    }

    1. Dear reader, I also need to spare some time to look into your code. You can start modifying from my code, and reach to your implementation.

  5. Dear Vikas,

    I have downloaded your program it’s working fine. But I am getting compile time error in following two lines.

    1. holder.caption.setText(myItems.get(position).caption);

    2. myItems.get(position).caption = Caption.getText().toString();

    I am getting myItems.get(position).caption error in this part. Whether I have to type cast any thing if yes then can you tell me how I have to do this.

  6. Dear Vikas,

    Thanks a lot for your reply. But it seems that my problem is not getting sorted out. Can you please tell me what changes I have to do in your program because i have copied Line by Line and I am getting compile time error in following two line..

    1. holder.caption.setText(myItems.get(position).caption);

    2.myItems.get(position).caption = Caption.getText().toString();

    what changes I have to do in above line so that My compile time error will be remove.

  7. Compilation error: caption cannot be resolved or is not a field
    1. Can you plz look into this issue. If You are not getting this compilation error, can you plz tell me which android sdk are you using.?

    1. Firstly. Thanks for Sharing Code

      Secondly i was getting compilation error on following lines.
      1. holder.caption.setText(myItems.get(position).caption);
      2. myItems.get(position).caption = Caption.getText().toString();

      I have replaced it with
      1. holder.caption.setText(myItems.get(position).toString());
      2. myItems.set(position, Caption.getText().toString());

      And your code worked for me. Am i doing somethng wrong ?

      1. Please ignore my above comments. I got compilation error because
        I forgot the following classes.

        class ViewHolder {
        90 EditText caption;
        91 }
        92
        93 class ListItem {
        94 String caption;
        95 }

  8. sir,plz help me out…….
    i added gallery view,image view…list of images to be display is stored in array….i perform all required settings…n i implement onclick event correctly,,i mean after clicking image in gallery view it will get displayed in image view……now problem is while implementing onfocuse change event……i want to display image which get focused while i rotate my horizontal scroll view…..please help……
    gallery.setOnFocusChangeListener(new OnFocusChangeListener()
    {
    @Override
    public void onFocusChange(View v, boolean hasFocus)
    {
    //////
    });

  9. Hi Vikas..thanks for your post.
    i am unable to get the listview row click event, If listview items(like edittext etc.) are having focus. May i know how can i achieve this.

    Thanks

    1. Since EditText can have click event, so it is clear confusion to Android that, whether it should call List item click event or list item has an EditText, and that EditText on click event. This is why you are not getting the listView’s click event, and you’ll get the EditText’s click event.
      Yon can end up in this situation by using the item select event. I hope this will still work.

  10. I am working on similar code except that the EditText is populated from database cursor instead of ArrayList. When user edits the EditText the new value is not bound the editText field it is still taking value from cursor.

  11. At start , we need to click two times on same row , to make edittext focusable. Otherwise it is possible to edit value in Edittext.

  12. hello guys.i am creating list view.list was created but how to enter in that list view item?i tried..
    guys…i am creating 5 list view items..i want insert data in that item?so it is possible?

  13. Hi!….I have another problem…..
    How can we add data to the multi column list view from edittext using add button?
    Please help me showing an example…
    Thank you..

  14. hello i am using above code. it works fine. but if keypad comes if i click on edittext means it focus another edittext.. how to solve this error ..please reply fast

  15. Hi guys,
    I am facing the same problem as others .
    it says cannor resolve caption

    holder.caption.setText(myItems.get(position).caption);

    myItems.get(position).caption = Caption.getText().toString();

    Above many people have asked the same question but no one has answered it firmly.
    Please can somebody post the answer.

    1. public class MyAdapter extends BaseAdapter {
      34 private LayoutInflater mInflater;
      35 public ArrayList myItems = new ArrayList();
      36 ViewHolder holder;
      .
      .
      .
      .

      .

      //we need to update adapter once we finish with editing
      75 holder.caption.setOnFocusChangeListener(new OnFocusChangeListener() {
      76 public void onFocusChange(View v, boolean hasFocus) {
      77 if (!hasFocus){
      78 final int position = v.getId();
      79 final EditText Caption = (EditText) v;
      80 myItems.get(position).caption = holder.caption.getText().toString();
      81 }
      82 }
      83 });

      please check line 36 and 80

  16. Thank you Vikas. It is really good article. I was trying this for two days and found the answer here. Superb.

  17. Thanks Vikas, I need to do the same but in the end to push a button to scroll the ListView and show me by post the information on the EditText

  18. //Fill EditText with the value you have in data source
    holder.caption.setText(myItems.get(position).caption); // Here the error – you must explicitly cast type

    holder.caption.setText( ((ListItem)myItems.get(position)).caption);

    1. Change

      public ArrayList myItems = new ArrayList(); at line 35

      to

      public ArrayList myItems = new ArrayList();

      1. looks like greater than and less than symbol cannot be displayed.

        just convert less than and greater than in its symbol –

        public ArrayList greater than ListItem less than myItems = new ArrayList greater than ListItem less than();

        peace.. 🙂

        Change

        public ArrayList myItems = new ArrayList(); at line 35

        to

        public ArrayList&ltListItem&gt myItems = new ArrayList();

    2. looks like greater than and less than symbol cannot be displayed.

      just convert less than and greater than in its symbol –

      public ArrayList less than ListItem greater than myItems = new ArrayList less than ListItem greater than();

      peace..

      Change

      public ArrayList myItems = new ArrayList(); at line 35

      to

      public ArrayList&ltListItem&gt myItems = new ArrayList();

      Your comment is awaiting moderation.

  19. Hello Vikas,,, I am getting error: “caption cannot be resolved or is not a field” in these two lines of your code…
    1.) holder.caption.setText(myItems.get(position).caption);
    2.) myItems.get(position).caption = Caption.getText().toString();
    Would you please help me with this… Thank you…

    1. Heyy, i solved the problem, but whats this ?? Any modification done to the value of any editText does not persist after scrolling listview up and down. Will you please fix this or if you can provide any tutorial or reference material, would be grateful to you… Thanks.

  20. solution for the error which most of u are facing :

    1. holder.caption.setText(((ListItem)myItems.get(position)).caption);
    2 . ((ListItem)myItems.get(position)).caption = Caption.getText().toString();

  21. Than You rupali for your good post that is very help full for me .

    output:- when change the the value of one Edit Text Then the same value is set at all Edit Text.But I want to change the value respective Edit Text. how that will possible…plz reply …

  22. Hi it works well, but i have an issue, i have 10 edittexts, 8 are visibile on the screen, 2 needs to scroll. While editting (by using the actionNext), it stops on the 8th item. i had to scroll and reclick on 9th item in order to continue. is there any way to edit it all the way till the end of the listview? Thanks, i would really appreciate your help in this.

  23. is to get the text so that the User finished typing in EditText, instead of setting the automatic text edit. For example, a list of products and each item one edit to the User inform the value of the product, and when they click a button to confirm it retrieves the text of edit values ​​that have been reported. Sorry for my english.

  24. Hi, I am facing a problem using the code in devices which have Samsung touchwiz software.
    When I tap on an EditText which is at the bottom of the screen, the softkeyboard pops up as expected while the listview slides up placing the EditText above the keyboard. However, once I begin typing, the ListView slides back down and the EditText is now behind the softkeyboard obstructing the view of the typing. I am still able to type, but the EditText is covered by the softkeyboard. Can you please confirm if you face the same kind of problem in samusng devices, and the cause/solution for the same

  25. change line 35 to public ArrayList greaterthan ListItem lessthan myItems = new ArrayList greaterthan ListItem lessthan();

  26. I have two button(+,-) and one edittext when i click + button show the increment value in edittext and click – button decrease the value in edittext what should i do please help me

  27. Hi.. I have one doubt. I typed some text in 0th position. Now I did not select any other editext and I scroll the list up to end. Now I come back to 0th position. Now the 0th position is empty or old value will replaced. Not new string will updated. Is there any way to solve this issue??

  28. Thank you, your code is working fine except one little problem I faced, I have 10 Edittext Fields and all of them works correctly except the last Edittext which always returns null, Could you please help me in that

  29. I want to thank you and ask you if you can you make a tutorial video about how to do this and explain more for beginners because I did not understand some things and I got those errors everyone is talking about but did not know how to deal with it..
    thank you again

  30. hi Sir, i have two EditText in the list view one for wholesale price and the other for retail price. My purpose here is to allow the user to update price of multiple products. Following ur instructions, i could update the first EditText which is wholesale price. for the retailprice Im getting back the same old value, even after editing. Please advise me on this. Thank you.

Leave a comment