Thursday, September 1, 2016

Android Custom ListView with a Button. (How to add a Button to an Android Custom ListView.)



1. Android ListView with Button

Many types of widgets are used in an Android Custom ListView. I introduced the Custom ListView having an ImageView and TextViews at [Android Custom ListView. (How to customize an Android ListView.)].
In this article, I'll explain that how to add button to an Android Custom ListView.

2. Adding a Button to the ListView

The item of the ListView is organized as follows.
ListView item's layout

2.1 Workflow

Workflow for the Custom ListView with a Button

2.2 Add a ListView to the Activity.

Declare "<ListView>" to "content_main.xml"(or "activity_main.xml") that is layout resource XML file of MainActivity.
[STEP-1] "content_main.xml" - Declare "<ListView>"
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.madwin.listviewbuttonexample.MainActivity"
    tools:showIn="@layout/activity_main">

    <ListView
        android:id="@+id/listview1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

2.3 Configure the ListView item's layout.

Add the item's layout XML file. The file name is "listview_btn_item.xml".
[STEP-2] "/res/layout/listview_btn_item.xml" - Configure ListView item's layout.
<?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:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/imageView1"
        android:layout_weight="1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text=""
        android:id="@+id/textView1"
        android:textSize="16dp"
        android:textColor="#000000"
        android:gravity="center_vertical"
        android:layout_weight="4" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="Select No"
        android:layout_weight="1" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="Execute Toast"
        android:layout_weight="1" />

</LinearLayout>

2.4 Define class for the ListView item.

Do you remember that you define class for the Custom ListView item at [Android Custom ListView. (How to customize an Android ListView.)]? Define class in the same way.
[STEP-3] "ListViewBtnItem.java" - Define class for ListView item.
import android.graphics.drawable.Drawable;

public class ListViewBtnItem {
    private Drawable iconDrawable ;
    private String textStr ;

    public void setIcon(Drawable icon) {
        iconDrawable = icon ;
    }
    public void setText(String text) {
        textStr = text ;
    }

    public Drawable getIcon() {
        return this.iconDrawable ;
    }
    public String getText() {
        return this.textStr ;
    }
}

2.5 Implement the custom adapter.

In this example, I use an ArrayAdapter instead of a BaseAdapter.
[STEP-4] "ListViewBtnAdapter.java" - Implement the custom adapter.
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

public class ListViewBtnAdapter extends ArrayAdapter implements View.OnClickListener  {
    // define a listener interface for Button click event.
    public interface ListBtnClickListener {
        void onListBtnClick(int position) ;
    }

    // save the resource id from the constructor.
    int resourceId ;
    // save ListBtnClickListener from the constructor.
    private ListBtnClickListener listBtnClickListener ;


    // the constructor of ListViewBtnAdapter
    ListViewBtnAdapter(Context context, int resource, ArrayList<ListViewBtnItem> list, ListBtnClickListener clickListener) {
        super(context, resource, list) ;

        // copy resource id.
        this.resourceId = resource ;

        this.listBtnClickListener = clickListener ;
    }

    // return the view for the item.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position ;
        final Context context = parent.getContext();

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(this.resourceId/*R.layout.listview_btn_item*/, parent, false);
        }

        // get the view widget's reference.
        final ImageView iconImageView = (ImageView) convertView.findViewById(R.id.imageView1);
        final TextView textTextView = (TextView) convertView.findViewById(R.id.textView1);

        // get the item data.
        final ListViewBtnItem listViewItem = (ListViewBtnItem) getItem(position);

        // update view by the item data.
        iconImageView.setImageDrawable(listViewItem.getIcon());
        textTextView.setText(listViewItem.getText());

        // process button1 click event.
        Button button1 = (Button) convertView.findViewById(R.id.button1);
        button1.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                textTextView.setText(Integer.toString(pos + 1) + " item is selected.");
            }
        });

        // save the position to button2's tag and set this adapter as the click event listener.
        Button button2 = (Button) convertView.findViewById(R.id.button2);
        button2.setTag(position);
        button2.setOnClickListener(this);

        return convertView;
    }

    // process button2 click event.
    public void onClick(View v) {
        if (this.listBtnClickListener != null) {
            this.listBtnClickListener.onListBtnClick((int)v.getTag()) ;
        }
    }

}


2.6 Add the function for loading sample data.

Add the function for loading sample data.
[STEP-5] "MainActivity.java" - load data.
    public boolean loadItemsFromDB(ArrayList<ListViewBtnItem> list) {
        ListViewBtnItem item ;
        int i ;

        if (list == null) {
            list = new ArrayList<ListViewBtnItem>() ;
        }

        i = 1 ;

        // create items.
        item = new ListViewBtnItem() ;
        item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_account_box_black_36dp)) ;
        item.setText(Integer.toString(i) + " item.") ;
        list.add(item) ;
        i++ ;

        item = new ListViewBtnItem() ;
        item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_account_circle_black_36dp)) ;
        item.setText(Integer.toString(i) + " item.") ;
        list.add(item) ;
        i++ ;

        item = new ListViewBtnItem() ;
        item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_language_black_36dp)) ;
        item.setText(Integer.toString(i) + " item.") ;
        list.add(item) ;
        i++ ;

        item = new ListViewBtnItem() ;
        item.setIcon(ContextCompat.getDrawable(this, R.drawable.ic_lightbulb_outline_black_36dp)) ;
        item.setText(Integer.toString(i) + " item.") ;
        list.add(item) ;

        return true ;
    }

2.7 Create the Adapter and set it to the ListView.

Create the Adapter and set it to the ListView.
[STEP-6] "MainActivity.java" - Create the Adapter and set it to the ListView in onCreate().
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ListView listview ;
        ListViewBtnAdapter adapter;
        ArrayList<ListViewBtnItem> items = new ArrayList<ListViewBtnItem>() ;

        // load items.
        loadItemsFromDB(items) ;

        // create the adapter.
        adapter = new ListViewBtnAdapter(this, R.layout.listview_btn_item, items, this) ;

        // set the adapter to the ListView.
        listview = (ListView) findViewById(R.id.listview1);
        listview.setAdapter(adapter);
    }

2.8 Process Button's click event.

Below codes were already wrote in previous steps.
But I'll write them once more for showing that how to process the button's click event.
"[STEP-7.1]" shows that how to process the button's simple click event.
[STEP-7.1] "ListViewBtnAdapter.java" - process button1 click event
    // process button1 click event.
    Button button1 = (Button) convertView.findViewById(R.id.button1);
    button1.setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            textTextView.setText(Integer.toString(pos + 1) + " item is selected.");
        }
    });
"[STEP-7.2] ~ [STEP-7.5]" shows that how to transfer the ListView item's click event to MainActivity.
[STEP-7.2] "ListViewBtnAdapter.java" - define a listener interface for Button click event.
public class ListViewBtnAdapter extends ArrayAdapter implements View.OnClickListener  {
    // define a listener interface for Button click event.
    public interface ListBtnClickListener {
        void onListBtnClick(int position) ;
    }

    // save ListBtnClickListener from the constructor.
    private ListBtnClickListener listBtnClickListener ;

    // ...
}
[STEP-7.3] "ListViewBtnAdapter.java" - add the listener to constructor's parameter.
public class ListViewBtnAdapter extends ArrayAdapter implements View.OnClickListener  {

    // ...

    ListViewBtnAdapter(Context context, int resource, ArrayList<ListViewBtnItem> list, ListBtnClickListener clickListener) {
        super(context, resource, list) ;

        // copy resource id.
        this.resourceId = resource ;

        this.listBtnClickListener = clickListener ;
    }

    // ...
}
[STEP-7.4] "ListViewBtnAdapter.java" - call onListBtnClick() of ListBtnClickListener.
    // process button2 click event.
    public void onClick(View v) {
        // call onListBtnClick() of ListBtnClickListener.
        if (this.listBtnClickListener != null) {
            this.listBtnClickListener.onListBtnClick((int)v.getTag()) ;
        }
    }
[STEP-7.5] "MainActivity.java" - extends ListViewBtnAdapter.ListBtnClickListener.
public class MainActivity extends AppCompatActivity implements ListViewBtnAdapter.ListBtnClickListener {

    // ...

    @Override
    public void onListBtnClick(int position) {
        Toast.makeText(this, Integer.toString(position+1) + " item is selected.", Toast.LENGTH_SHORT).show() ;
    }
}

2.9 Build and run.

Build and run "app".

3. Screenshot.

Screenshot1 of the Custom ListView with a Button

Screenshot2 of the Custom ListView with a Button

4. References.

.END.

No comments:

Post a Comment