Wednesday, February 6, 2013

Multi Touch List View : Multi Click List View Demo in Android : Click button in List View in Android

Hello friends,

Today I am going to share very Important code for Multi-Clickable  Listview in Android.
Suppose you want perform multiple task on click of Listview like- edit, delete, share and go to another activity etc in this case my blog will help you. For this I am using custom Array-adapter. Screen shot and code is given below step by step-

1-Print Screen:

a)Normal view-

b)Main List View Clicked-

c)Edit Button Clicked-

d)Delete Button Clicked-


  2) Create MainActivity.java class
package com.example.multitouchlistview;


import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {
ListView userList;
UserCustomAdapter userAdapter;
ArrayList<User> userArray = new ArrayList<User>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

/**
* add item in arraylist
*/
userArray.add(new User("Mumer", "Spain", "Spain"));
userArray.add(new User("Jon", "EW", "USA"));
userArray.add(new User("Broom", "Span", "SWA"));
userArray.add(new User("Lee", "Aus", "AUS"));
userArray.add(new User("Jon", "EW", "USA"));
userArray.add(new User("Broom", "Span", "SWA"));
userArray.add(new User("Lee", "Aus", "AUS"));
/**
* set item into adapter
*/
userAdapter = new UserCustomAdapter(MainActivity.this, R.layout.row,
userArray);
userList = (ListView) findViewById(R.id.listView);
userList.setItemsCanFocus(false);
userList.setAdapter(userAdapter);
/**
* get on item click listener
*/
userList.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View v,
final int position, long id) {
Log.i("List View Clicked", "**********");
Toast.makeText(MainActivity.this,
"List View Clicked:" + position, Toast.LENGTH_LONG)
.show();
}
});

}

}


  3)Create UserCustomAdapter.java for custom view

package com.example.multitouchlistview;

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class UserCustomAdapter extends ArrayAdapter<User> {
Context context;
int layoutResourceId;
ArrayList<User> data = new ArrayList<User>();

public UserCustomAdapter(Context context, int layoutResourceId,
ArrayList<User> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
UserHolder holder = null;

if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new UserHolder();
holder.textName = (TextView) row.findViewById(R.id.textView1);
holder.textAddress = (TextView) row.findViewById(R.id.textView2);
holder.textLocation = (TextView) row.findViewById(R.id.textView3);
holder.btnEdit = (Button) row.findViewById(R.id.button1);
holder.btnDelete = (Button) row.findViewById(R.id.button2);
row.setTag(holder);
} else {
holder = (UserHolder) row.getTag();
}
User user = data.get(position);
holder.textName.setText(user.getName());
holder.textAddress.setText(user.getAddress());
holder.textLocation.setText(user.getLocation());
holder.btnEdit.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Edit Button Clicked", "**********");
Toast.makeText(context, "Edit button Clicked",
Toast.LENGTH_LONG).show();
}
});
holder.btnDelete.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Delete Button Clicked", "**********");
Toast.makeText(context, "Delete button Clicked",
Toast.LENGTH_LONG).show();
}
});
return row;

}

static class UserHolder {
TextView textName;
TextView textAddress;
TextView textLocation;
Button btnEdit;
Button btnDelete;
}
}


4)Create User.java class

package com.example.multitouchlistview;

public class User {
String name;
String address;
String location;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

public User(String name, String address, String location) {
super();
this.name = name;
this.address = address;
this.location = location;
}

}

5)Create 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"
    android:background="#0099CC"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Multi Touch Listview"
        android:textColor="#FFFFFF"
        android:textSize="25sp" />

    <ListView
        android:id="@+id/listView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@+id/textView"
        android:layout_marginTop="5dp"
        android:cacheColorHint="#00000000" />

</RelativeLayout>

6)Create custom layout for view row.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"
    android:padding="5dp"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="User Name"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="5dp"
        android:text="Address"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="16sp" />

    <Button
        android:id="@+id/button1"
        android:layout_width="80dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="#FFFFFF"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="Edit Data"
        android:textColor="#0099CC" />

    <Button
        android:id="@+id/button2"
        android:layout_width="80dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/button1"
        android:layout_marginTop="3dp"
        android:background="#FFFFFF"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:text="Delete"
        android:textColor="#0099CC" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView2"
        android:layout_marginTop="5dp"
        android:text="Location" />

</RelativeLayout>

Note- Don't forget to add below line in Button View-
  android:focusable="false"
  android:focusableInTouchMode="false"

67 comments :

  1. Hey, great end to end example! So far the best I found :) Thanks!

    ReplyDelete
    Replies
    1. Your welcome Adam & thanks for nice comments...

      Delete
  2. is it possible to insert 2 different textview in different list item?
    example:
    ListItem1 = TextView1
    ListItem2 = TextView2

    ReplyDelete
    Replies
    1. I did not got what you want here with 2 list view?

      Delete
  3. please help me. how can we add multiple images for gallery in array list for different items

    ReplyDelete
    Replies
    1. from gallery or for gallery? Please clear your requirement..

      Delete
  4. Hello. Thank you for spending your time on publishing this.

    I am confused about the row.xml.
    Is it a complete new activity og just a standalone XML file placed in layout folder?

    ReplyDelete
    Replies
    1. row.xml is used for create custom adapter for list-view. Please don't be confused this is this is separate view for custom list view..

      Delete
  5. Thank you Again. Confusion is solved :)

    Another thing I was wondering about is how to read what button is clicked. I mean which row does the button click belong to..

    I know you get seperate information on if it is the edit button or the delete button, but I dont see how to actually see which row the edit or delete button belongs to.

    Maybe I am blind and if that is the case then I am sorry :)

    ReplyDelete
    Replies
    1. Please see here-
      Just get the position of button...

      holder.btnEdit.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
      // TODO Auto-generated method stub
      Log.i("Edit Button Clicked", "**********");
      Toast.makeText(context, "Edit button Clicked"+position,
      Toast.LENGTH_LONG).show();
      }
      });

      Delete
  6. THank you. That worked.
    I just had to change:
    public View getView(int position, View convertView, ViewGroup parent) {

    to:
    public View getView(final int position, View convertView, ViewGroup parent) {

    Else I wasnt able to Refer to position within the onclick method.

    Thank you Again.

    ReplyDelete
  7. I was wondering about another issue.

    I think this might be more generally about customadapters than just this code you gave us.

    Is it posible from the mainactivity class to actually iterate through the listview and also read the buttons state that are placed in the adapter?

    Also is it possible to pass the onClick position from the adapter directly to the activity so I can use the position information IN the activity rather than in the adapter?

    I know I am asking alot from you and that you probably have plenty of other Things to spend your time on, but I seem to get stuck on finding this information myself.

    ReplyDelete
    Replies
    1. Ok just ignore my last post. I figured it out.

      Delete
  8. Hi

    I want to delete the particular row only when delete button is pressed. Please help me.

    ReplyDelete
    Replies
    1. So from where you are getting data ? from sqlite, web-service? or in local array?
      just delete that item from list or array and refill your adapter..

      Thanks!

      Delete
    2. Thanks!
      I am fetching data from sqlite, But I want to delete it using setTag & getTag method to reduce database query overhead.

      Delete
    3. additionally I want to display the data in next activity when user clicks edit data button.

      Delete
    4. Hi,

      1)In this case you have to pass delete query. suppose you delete item from local object and when user come again on that page item will be there again because it is still in your database. Right?
      No worry about overhead, now in these days our mobile device have good processor and ram.

      2)Just use get single record activity and display that data on next page and after edit you record just pass update query..

      Thanks!

      Delete
  9. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Please don't remove comments, just write new comment if needed..
      Else it will reduce my traffic.

      Delete
  10. Hey there!! thanks for this wonderful tutorial; i have implemented your code in Fragments. As in i call the (above)List view by Button Click from Swipey Tabs. All working cool . Just a Problem that i m getting is whenever i click the list View i dont get the Toast "List View is Clicked". Can u Figure out the problem Please

    ReplyDelete
  11. I can't guess anything without code. Any way I think problem with "this" keyword. try to use getParrant(), getApplicationContext() or something else.
    And please try to print log first you are getting anything there or not?

    ReplyDelete
  12. Awesome post. I recommend it to my android classmates in HK.

    ReplyDelete
  13. Note- Don't forget to add below line in Button View-
    android:focusable="false"
    android:focusableInTouchMode="false"

    if we set this true, unable to click listview. Could you explain why? Thanks for your effort in posting the code. Thanks a lot.

    ReplyDelete
    Replies
    1. Hi Sreelal, i am not sure why its happen exactly. i think this is android bug only any way i got some where this thing-
      in nested Views, the child view always gets all the touch events first. if you want the parent view (in your case, the listView row), to get a touch event, you must return false on the child events or set them to be android:clickable="false"

      hope it will help you to understand that..

      Thanks!

      Delete
  14. I have the forms whenever form submit button clicked that all form data will be stored into one json object and that json object stored in on column of database.again whenever submit the form i have to print the list msg in another activity like your new meter is installed.Just like I have seven forms whenever click those forms that msgs also will be append to previous msgs in listview. here there is no problem to me
    problem happends in this
    in listview one imageview is there whenever click that image i want to retreive particular msg json object and that object data will be displayed in another activity list

    ReplyDelete
    Replies
    1. so what problem you are facing? do some thing like that-
      holder.btnEdit.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
      Intent intent=new Intent(context,B.class)
      //you can pass here that json object in putExtra
      startActivity(intent);
      }
      });

      or you can just pass next page that column id and on that page from database retrive detail of that image.

      Delete
    2. This comment has been removed by the author.

      Delete
  15. Hi Manish,
    A million thanks for ur wonderful tutorial!!!

    I want to go to page "detail" when clicked the "detail" image. But the problem is when I write "startActivity(intent);" it tell me to create the startActivity method, that should not happen right?

    And "android:focusable="false"" also make me a little bit confused. If it is set to be unfocusable, how can it respond to click event?

    Thanks!
    Lijin

    ReplyDelete
  16. hi just use this line-

    Intent intent=new Intent(context,A.class);
    context.startActivity(intent);

    ReplyDelete
  17. tnx for your reply..

    telugu language is not supported in android mobiles.if any plugin is there...plz help me......

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. i hv a image listview when i click a image then opened image
    can u suggest me how to do this.

    ReplyDelete
    Replies
    1. use onItemClickListner for your listview and on click that image open new activity and display that image on next page. see this post hope it will help you-

      http://www.androidhub4you.com/2013/04/sqlite-example-in-android-add-image.html

      just copy, click and go to next page code..

      Thanks!

      Delete
  20. thanks, its work like charm ..

    ReplyDelete
  21. hi, your tutorial great and i manage to delete data from the database
    but why don't it reflect in my list ?

    ReplyDelete
    Replies
    1. It is deleted from database but your list-view is not refreshed. So re-create your list-view or use notify change or some other mechanism to do this task.

      Delete
  22. I want textview data of particular button clicked row.when user clicked on button it display textview data on toast of particular row.

    ReplyDelete
    Replies
    1. so simple just put your value in any string type variable and then display it on toast-
      String valueText=user.getName();

      And now pass it in your Toast-
      Toast.makeText(context, valueText,
      Toast.LENGTH_LONG).show();

      Delete
  23. how to update the list view after delete. also how to update the set text after selecting particular row in the list view.

    ReplyDelete
  24. hi this s code working fine .but can u tell me how can i save the listview items in database after delete button.actually i want those items further use

    ReplyDelete
  25. nice tutorial, One cuestion, I have gridview with listview but the listview only show 2 items on the list when the arrayList have 10 items.
    Some solution?
    thanks

    ReplyDelete
  26. Manish Srivastava,

    I just want to say you are such as great man. Thank you very much for all what you do and share them with us. People like you in the world will be a peaceful place. Keep up with whatever you are doing my friend. Thanks a lot

    ReplyDelete
  27. Nice post, thank you. I was looking out for such post. It helped.

    ReplyDelete
  28. This comment has been removed by the author.

    ReplyDelete
  29. Thank you for your tutoial, how can I implement the delete function with database?


    ReplyDelete
    Replies
    1. Just execute delete query on delete button click. Make a connection from your database and execute your query.

      Delete
  30. wonderful tutorial Bro...thankyou :)...
    i tried implementing the same with edittexts instead of the buttons, i could do that but my problem araised when the edit text values started vanishing on scrolling the listview... how do i store the values entered in the edittext and display it at the same places even on scrolling, as i have to send all the data on edittexts to the database (server)... could you please help me on this... your reply means a lot to me

    ReplyDelete
    Replies
    1. I am not sure but yes you can mannage it using handler post delay. Please google it on stackoverflow.

      Delete
  31. Thanks its really help me a lot

    ReplyDelete
  32. public View getView(int position, View view, ViewGroup parent) {
    // TODO Auto-generated method stub
    LayoutInflater inflater = (LayoutInflater) mContext
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = inflater.inflate(R.layout.dialog_list_each_item, null);
    cursor.moveToPosition(position);
    String date = cursor.getString(cursor.getColumnIndex("T_date"));
    id_delete = cursor.getInt(cursor.getColumnIndex("_id"));

    Double payment = convert(cursor.getDouble(cursor
    .getColumnIndex("T_amount")));
    BigDecimal bd21 = new BigDecimal(payment);
    BigDecimal rounded = bd21.setScale(2, BigDecimal.ROUND_HALF_DOWN);

    TextView textViewdate = (TextView) view
    .findViewById(R.id.tv_startDateAndTime);
    TextView textViewcurrency = (TextView) view
    .findViewById(R.id.tv_currency);
    TextView textViewpayment = (TextView) view
    .findViewById(R.id.tv_transactionAmmount);
    Button btnEdit = (Button) view.findViewById(R.id.btn_edit);
    Button btnDelete = (Button) view.findViewById(R.id.btn_delete);

    textViewcurrency.setText(MyActivity.currency);
    textViewdate.setText(date);
    textViewpayment.setText(String.valueOf(rounded));
    btnEdit.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub

    Toast.makeText(mContext, "Edit ", Toast.LENGTH_SHORT).show();
    }
    });

    btnDelete.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {

    // TODO Auto-generated method stub
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
    mContext);

    // Setting Dialog Title
    alertDialog.setTitle("Confirm Delete...");

    // Setting Dialog Message
    alertDialog.setMessage("Are you sure you want delete this?");

    // Setting Icon to Dialog
    alertDialog.setIcon(R.drawable.delete);

    // Setting Positive "Yes" Button
    alertDialog.setPositiveButton("YES",
    new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog,
    int which) {
    // TODO Auto-generated method stub

    Log.d("Delete ID :", id_delete + "");
    invoice.db
    .execSQL("delete from Transactions where _id="
    + id_delete + "");
    // Write your code here to invoke YES event
    Toast.makeText(mContext, "Shift deleted",
    Toast.LENGTH_SHORT).show();

    int I_id = MyActivity.Iid;
    int I_type = MyActivity.invoice_flag;
    Intent myIntent = new Intent(mContext,
    InvoiceDialogActivity.class);
    myIntent.putExtra("ID", I_id);
    myIntent.putExtra("Type", I_type);
    mContext.startActivity(myIntent);
    }
    });
    alertDialog.setNegativeButton("No",
    new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog,
    int which) {
    // TODO Auto-generated method stub
    dialog.dismiss();
    }
    });
    alertDialog.show();

    Toast.makeText(mContext, "Delete ", Toast.LENGTH_SHORT).show();

    }
    });

    return view;
    }


    trying to delete record from database but it not give me exact id on delete click it get always last id of the cursor!! please help.

    ReplyDelete
  33. Hey, very useful tutorial. Great job! Thanks, Manish :)

    ReplyDelete
  34. Hi Manish,
    1 Question .
    I get the Toast Message and EveryThing OK.
    But I want delete or add the item of the row, So I Have this information in my UserCustomAdapter but in this class I can't access to my BD. I don't want start another activity. Thanks

    ReplyDelete
    Replies
    1. BD means? Database osomething else?

      Delete
    2. Yes , Sorry BD = Databases.
      Sorry for may Bad English I sepak Spanish.
      Thanks

      Delete
    3. Are you able to add remove item from activity class? If yes share the code i will change for adaptar.

      Delete
    4. In this code , I add but when the USER Touch the listView. EXCEPT THE BUTTON

      list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

      @Override
      public void onItemClick(AdapterView parent, View view, int position, long id) {
      //ComprasDataSource.crearNota(position);
      Toast.makeText(PantallaNueva.this, "You Clicked " + Elementos.get(position), Toast.LENGTH_SHORT).show();
      db = oData.getWritableDatabase();
      db.execSQL("insert into [carrito] ([_id_prod]) values ( " + Referencias.get(position) + ")");

      int count = oData.CuentaRegistros(db);

      TextView textview = (TextView)findViewById(R.id.textView20);

      if(count == 1)
      {
      textview.setText("Hay " + count + " producto");
      }else{
      textview.setText("Hay " + count + " productos");
      }
      }
      });

      When I try to add this item in the CustomList , DOn't let me because I try to create the Databases and say me I can't

      Delete