9 Dec 2014

Edittext in listview | Focusable EditText inside ListView in android

There is a common issue which we are facing in EditText in side listview.

-Issue with focus of edit text within listview row.
-Reset editText value while scrolling listview.

I have found some solutions to overcome this kind of issue in listview.

Note : we can solved any of issue which is related with listview using this sample.

OUTPUT SCREEN :







activity_list_view.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:descendantFocusability="beforeDescendants"
        tools:listitem="@layout/row_item" >
    </ListView>

</RelativeLayout>

 

row_item.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <EditText
        android:id="@+id/edVal1"
        android:layout_width="0sp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:inputType="numberDecimal"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <EditText
        android:id="@+id/edValue2"
        android:layout_width="0sp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:inputType="numberDecimal"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <TextView
        android:id="@+id/txtTotal"
        android:layout_width="0sp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Total"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <ImageButton
        android:id="@+id/ibDelete"
        android:layout_width="@dimen/width_button"
        android:layout_height="fill_parent"
        android:background="@null"
        android:contentDescription="@string/app_name"
        android:onClick="itemDeleteListner"
        android:src="@drawable/ic_delete" />

</LinearLayout>


Bean :

import java.io.Serializable;

public class Bean implements Serializable
{
       private static final long serialVersionUID = -5435670920302756945L; 
       private int val1 =0;
       private int val2 =0;
       private double Total = 0;

       public int getVal1() {
              return val1;
       }

       public void setVal1(int val1) {
              this.val1 = val1;
       }

       public int getVal2() {
              return val2;
       }

       public void setVal2(int val2) {
              this.val2 = val2;
       }

       public double getTotal() {
              return Total;
       }

       public void setTotal(Double total) {
              Total = total;
       }
      
}

ItemListAdapter :

import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

public class ItemListAdapter extends ArrayAdapter<Bean>
{
       protected static final String LOG_TAG = ItemListAdapter.class.getSimpleName();

       private ArrayList<Bean> items;
       private int layoutResourceId;
       private Context context;

       public ItemListAdapter(Context context, int layoutResourceId, ArrayList<Bean> items)
       {
              super(context, layoutResourceId, items);
              this.layoutResourceId = layoutResourceId;
              this.context = context;
              this.items = items;
       }

       @SuppressLint("ViewHolder")
       @Override
       public View getView(int position, View convertView, ViewGroup parent)
       {
              View row = convertView;
              Holder holder = null;

              LayoutInflater inflater = ((Activity) context).getLayoutInflater();
              row = inflater.inflate(layoutResourceId, parent, false);

              holder = new Holder();
              holder.bean = items.get(position);
              holder.ibDelete = (ImageButton)row.findViewById(R.id.ibDelete);
              holder.ibDelete.setTag(holder.bean);

              holder.etVal1 = (EditText)row.findViewById(R.id.edVal1);
              holder.etVal2 = (EditText)row.findViewById(R.id.edValue2);
              holder.tvTotal=(TextView) row.findViewById(R.id.txtTotal);

              setVal1TextChangeListener(holder);
              setVal2TextListeners(holder);           

              row.setTag(holder);
             
              setupItem(holder);

              return row;
       }

       private void setupItem(Holder holder)
       {
              holder.etVal1.setText(String.valueOf(holder.bean.getVal1()));
              holder.etVal2.setText(String.valueOf(holder.bean.getVal2()));
              holder.tvTotal.setText(String.valueOf(holder.bean.getTotal()));
       }

       public static class Holder
       {
              Bean bean;
              EditText etVal1;
              EditText etVal2;
              TextView tvTotal;
              ImageButton ibDelete;
       }

       private void setVal1TextChangeListener(final Holder holder)
       {
              holder.etVal1.addTextChangedListener(new TextWatcher()
              {

                     @Override
                     public void onTextChanged(CharSequence s, int start, int before, int count)
                     {
                           if(s.toString().length()>0)
                                  holder.bean.setVal1(Integer.parseInt(s.toString()));
                     }

                     @Override
                     public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

                     @Override
                     public void afterTextChanged(Editable s) { }
              });
       }

       private void setVal2TextListeners(final Holder holder)
       {
              holder.etVal2.addTextChangedListener(new TextWatcher()
              {

                     @Override
                     public void onTextChanged(CharSequence s, int start, int before, int count)
                     {
                           try
                           {
                                  if(s.toString().length()>0)
                                  {
                                         holder.bean.setVal2(Integer.parseInt(s.toString()));                                    
                                  }
                           }
                           catch (NumberFormatException e)
                           {
                                  Log.e(LOG_TAG, "error reading double value: " + s.toString());
                           }
                     }

                     @Override
                     public void beforeTextChanged(CharSequence s, int start, int count, int after)
                     {
                          
                     }

                     @Override
                     public void afterTextChanged(Editable s)
                     {
                           if(s.toString().length()>0)
                           {
                                  holder.bean.setVal2(Integer.parseInt(s.toString()));
                                 
                                  double val1=Double.parseDouble(holder.etVal1.getText().toString());
                                  double val2=Double.parseDouble(holder.etVal2.getText().toString());                            
                                  holder.bean.setTotal(val1*val2);                             

                                  holder.tvTotal.setText(String.valueOf(val1*val2));
                           }
                          
                     }
              });
       }
}


MainActivity :  


import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;

public class MainActivity extends Activity
{
       private ItemListAdapter adapter;
       ArrayList<Bean>arrayList=new ArrayList<Bean>();

       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_list_view);
             
              for (int i = 0; i < 20; i++)
              {
                     Bean atomPayment=new Bean();
                     atomPayment.setVal1(i);
                     atomPayment.setVal2(i);
                     arrayList.add(atomPayment);
              }
             
              adapter = new ItemListAdapter(MainActivity.this, R.layout.row_item,arrayList);
              ListView listView = (ListView)findViewById(R.id.listview);
              listView.setAdapter(adapter);
             
       }

       public void itemDeleteListner(View v)
       {
              Bean itemToRemove = (Bean)v.getTag();
              adapter.remove(itemToRemove);           
       }

}


I will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)

3 comments:

  1. I need listview edittext afterchanged data in Activity class how it possible? I need only edittext data.

    ReplyDelete
  2. Thank you, It helped a lot

    ReplyDelete
  3. its a great tutorial but when i click on any EditText the focus is changed to any random place and no written text is displayed
    please help.

    ReplyDelete