Android Custom Listview with EditText

For Custom Listview,  we need the following:-

  1. MainActivity class containing  Listview and will be the main screen.
  2. Create Model class to save data for each row like in this example I created MyItem class.
  3. Pass this Model class object to ArrayList to generate each row item of Listview.
  4. Create CustomAdapter class to have a view for each row as required in this example I created MyAdapter class to generate the view for each row.
  5. We need two layouts one for MainActivity class containing listview and other for CustomAdapter which we need for each row of the listview. we can create a view for CustomAdapter according to our requirement.

MainActivity.java

 

package com.androidruler.customlistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {

ListView mainactivity;
// creating arraylist of MyItem type to set to adapter
ArrayList<MyItem> myitems=new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainactivity=(ListView)findViewById(R.id.mainactivitylistview);
//Adding data i.e images and title to be set to adapter to populate list view
//here i am passing image id from drawable and string as to be set as title as 
// a parameter to MyItem Constructor as our ArrayList is type of MyItem

myitems.add(new MyItem(R.drawable.christ_brazil,"Christ Redeemer: Rio de Janeiro
Brazil"));
myitems.add(new MyItem(R.drawable.greatwall_china,"Great Wall of China: China"));
myitems.add(new MyItem(R.drawable.machu_peru,"Machu Picchu: Peru"));
myitems.add(new MyItem(R.drawable.petra_jorden,"Petra: Jordan"));
myitems.add(new MyItem(R.drawable.pyramid_mexico,"Pyramid at Chichén Itzá:YucataPeninsula, Mexico"));
myitems.add(new MyItem(R.drawable.roman_rome,"Roman Colosseum: Rome, Italy"));
myitems.add(new MyItem(R.drawable.taj_india,"Taj Mahal: Agra, India"));

//Creating Adapter object for setting to listview
MyAdapter adapter=new MyAdapter(MainActivity.this,myitems);
mainactivity.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_main, menu);
//this shows three dots at right corner on click settings open
return true; 
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{ return true; }
return super.onOptionsItemSelected(item);
}
}

//Model Class whose objects we pass in ArrayList

MyItem.java

public class MyItem {

    private int imageid;
    private String imageheading="";

    public MyItem(int id,String title)
    {
        imageid=id;
        imageheading=title;
    }

    public int getImageid() {
        return imageid;
    }

    public String getImageheading() {
        return imageheading;
    }

    public void setImageheading(String imageheading) {
        this.imageheading = imageheading;
    }

    public void setImageid(int imageid) {

        this.imageid = imageid;
    }
}

//Custom Adapter extends BaseAdapter

 MyAdapter.java

public class MyAdapter extends BaseAdapter {

    Context context;
    ArrayList<MyItem> listforview;
    LayoutInflater inflator=null;
    View v;
    ViewHolder vholder;
    //Constructor
    public MyAdapter(Context con,ArrayList<MyItem> list)
    {
        super();
        context=con;
        listforview=list;
        inflator=LayoutInflater.from(con);
    }

    // return position here
    @Override
    public long getItemId(int position) {
        return position;
    }

    // return size of list
    @Override
    public int getCount() {
        return listforview.size();
    }

    //get Object from each position
    @Override
    public Object getItem(int position) {
        return listforview.get(position);
    }

    //Viewholder class to contain inflated xml views
    private  class ViewHolder
    {
        TextView title;
        ImageView image;
    }
    // Called for each view
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        v=convertView;
        if(convertView==null)
        {
            //inflate the view for each row of listview
            v=inflator.inflate(R.layout.myadapter,null);
            //ViewHolder object to contain myadapter.xml elements
            vholder=new ViewHolder();
            vholder.title=(TextView)v.findViewById(R.id.adaptertextview);
            vholder.image=(ImageView)v.findViewById(R.id.adapterimage);
            //set holder to the view
            v.setTag(vholder);
        }
        else
            vholder=(ViewHolder)v.getTag();

        //getting MyItem Object for each position
        MyItem item=(MyItem)listforview.get(position);
//set the id to editetxt important line here as it will be helpful to set text according to position
vholder.title.setId(position);
//setting the values from object to holder views for each row vholder.title.setText(item.getImageheading()); vholder.image.setImageResource(item.getImageid());
        vholder.title.setOnFocusChangeListener(
        new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {

                if (!hasFocus) {
                   final int id = v.getId();
                    MyItem item = listforview.get(id);
                   final EditText field = ((EditText) v);
                    listforview.get(id).setImageheading(field.getText().toString());
                }
            }
        }
);
return v;
 }
 } 

//layout for MainActivity.java

activity_main.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"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/mainactivitylistview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:divider="@android:color/black"
        android:dividerHeight="2dp"
        android:descendantFocusability="afterDescendants"
        ></ListView>
 </RelativeLayout> 

//layout file for Adapter

myadapter.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/adapterimage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/adaptertextview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidruler.customlistview" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustPan"
           > 
<intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 </application>
 </manifest>