Introduction
Hi friends, this is my first article on C# Corner, I am Ravi Sharma, an Android developer.
This article is intended to make a custom listener on a button, that belongs to a list item. This article is another answer for the interview question “How to use an interface in Android?“.
Now to discuss the code to understand how to make a custom listener.
For doing this, first make a string array in a string file, this file is automatically generated in the value folder in the res folder as in the following:
Put the following code in this file,
- <string-array name="listdata">
- <item>item 1</item>
- <item>item 2</item>
- <item>item 3</item>
- <item>item 4</item>
- <item>item 5</item>
- <item>item 6</item>
- <item>item 7</item>
- <item>item 8</item>
- <item>item 9</item>
- <item>item 10</item>
- <item>item 11</item>
- <item>item 12</item>
- <item>item 13</item>
- <item>item 14</item>
- <item>item 15</item>
- <item>item 16</item>
- <item>item 17</item>
- <item>item 17</item>
- <item>item 18</item>
- <item>item 19</item>
- <item>item 20</item>
- </string-array>
Then make a layout for the activity with the code below,
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <ListView
- android:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
-
- </RelativeLayout>
Then make the child layout for the list, the code is below:
- <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:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context="com.example.articalonlistiner.MainActivity$PlaceholderFragment" >
-
- <TextView
- android:id="@+id/childTextView"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true" />
-
- <Button
- android:id="@+id/childButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:text="Click Me" />
-
- </RelativeLayout>
Now make the reference of the ListView and Adapter.
Make an activity (MainActivity.java) in the src folder.
Write that code in the MainActivity.
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/container"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <ListView
- android:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
-
- </RelativeLayout>
This code shows the error because you have not made the ListAdapter.java file in the src folder. Please make that file and extend it with ArrayAdapter<String>.
- public class ListAdapter extends ArrayAdapter<String>
Then make the constructor of the ListAdapter as in the following,
- public ListAdapter(Context context, ArrayList<String> dataItem) {
- super(context, R.layout.child_listview, dataItem);
- this.data = dataItem;
- this.context = context;
- }
There R.layout.child_listview is the child view of the ListView.
Now make an interface in ListAdapter, this interface works like a listener for the button.
- customButtonListener customListner;
-
- public interface customButtonListener {
- public void onButtonClickListner(int position,String value);
- }
And make a method to set the instance of the activity that has a ListView.
- public void setCustomButtonListner(customButtonListener listener) {
- this.customListner = listener;
- }
This method shares the context of the MainActivity with the interface to use this.
Make a child class in ListAdapter.
- public class ViewHolder {
- TextView text;
- Button button;
- }
If you have more items in the listItem view then add all the references in the ViewHolder class.
Now focus on the getview method of the adapter.
For this override the getView method.
- @Override
- public View getView(final int position, View convertView, ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- LayoutInflater inflater = LayoutInflater.from(context);
- convertView = inflater.inflate(R.layout.child_listview, null);
- viewHolder = new ViewHolder();
- viewHolder.text = (TextView) convertView
- .findViewById(R.id.childTextView);
- viewHolder.button = (Button) convertView
- .findViewById(R.id.childButton);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- final String temp = getItem(position);
- viewHolder.text.setText(temp);
- viewHolder.button.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (customListner != null) {
- customListner.onButtonClickListner(position,temp);
- }
-
- }
- });
-
- return convertView;
- }
Note- Here the yellow marked function is new for you. This is the main function to provide a listener for the button of each item of the list view. This function returns a callback for MainActivity because the MainActivity shares our context with the listener.
To use this you should implement this interface in MainActivity.
- public class MainActivity extends Activity implements
- customButtonListener
After implementing this, this interface overrides the method. The method gives you the position of the list adapter.
I implemented it only to show the toast. It is the code of my function.
- @Override
- public void onButtonClickListner(int position, String value) {
- Toast.makeText(MainActivity.this, "Button click " + value,
- Toast.LENGTH_SHORT).show();
-
- }
The output of this article is like,
You can implement your method, whatever you want to do with the button.
Here is the simple Toast.
This article is over now. The following is the entire code of the MainActivity and List Adapter.
MainActivity
- package com.example.articalonlistiner;
-
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
-
- import com.example.articalonlistiner.ListAdapter.customButtonListener;
-
- import android.os.Bundle;
- import android.support.v7.app.ActionBarActivity;
- import android.widget.ListView;
- import android.widget.Toast;
-
- public class MainActivity extends ActionBarActivity implements
- customButtonListener {
-
- private ListView listView;
- ListAdapter adapter;
- ArrayList<String> dataItems = new ArrayList<String>();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- String[] dataArray = getResources().getStringArray(R.array.listdata);
- List<String> dataTemp = Arrays.asList(dataArray);
- dataItems.addAll(dataTemp);
- listView = (ListView) findViewById(R.id.listView);
- adapter = new ListAdapter(MainActivity.this, dataItems);
- adapter.setCustomButtonListner(MainActivity.this);
- listView.setAdapter(adapter);
-
- }
-
- @Override
- public void onButtonClickListner(int position, String value) {
- Toast.makeText(MainActivity.this, "Button click " + value,
- Toast.LENGTH_SHORT).show();
-
- }
-
- }
ListAdapter
- package com.example.articalonlistiner;
-
- import java.util.ArrayList;
-
- import android.content.Context;
- 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;
-
- public class ListAdapter extends ArrayAdapter<String> {
- customButtonListener customListner;
-
- public interface customButtonListener {
- public void onButtonClickListner(int position,String value);
- }
-
- public void setCustomButtonListner(customButtonListener listener) {
- this.customListner = listener;
- }
-
- private Context context;
- private ArrayList<String> data = new ArrayList<String>();
-
- public ListAdapter(Context context, ArrayList<String> dataItem) {
- super(context, R.layout.child_listview, dataItem);
- this.data = dataItem;
- this.context = context;
- }
-
- @Override
- public View getView(final int position, View convertView, ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- LayoutInflater inflater = LayoutInflater.from(context);
- convertView = inflater.inflate(R.layout.child_listview, null);
- viewHolder = new ViewHolder();
- viewHolder.text = (TextView) convertView
- .findViewById(R.id.childTextView);
- viewHolder.button = (Button) convertView
- .findViewById(R.id.childButton);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- final String temp = getItem(position);
- viewHolder.text.setText(temp);
- viewHolder.button.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (customListner != null) {
- customListner.onButtonClickListner(position,temp);
- }
-
- }
- });
-
- return convertView;
- }
-
- public class ViewHolder {
- TextView text;
- Button button;
- }
- }
If anyone has a query then provide it in the comments.
Thank for reading.