Android Custom ListView with ImageView EditText and Button

Android Custom ListView with ImageView EditText and Button

In this article, we learn to implement a custom ListView for our Electronic Shop android app. Our custom ListView contains an ImageView for displaying product image, two TextView for the product name and product price, Two ImageButton for increment and decrements the quantity of the product to purchase and finally an EditText to display product quantity.

Below is the demo about What we achieve at the end of this article.

 

So, let's start the coding part. Below are the details about the project and its structure 
Android Studio Version: Android Studio 1.4.1

  • java
    • com.vlemonn.listviewedittextbutton
      • Products.java- (Class) Stores product data
      • ListAdapter.java- (Class) Custom List Adapter to populate the custom ListView
      • ListViewHolder.java- (Class) Custom ListView item holder.
      • MainActivity.java - (Class) Main Activity Java.
  • res
    • layout
      • activity_custom_listview.xml - Layout file for our custom ListView Items. In other words, you can say it is a template for our ListView Items
      • activity_main.xml - Layout file for the main activity.
    • mipmap-xxxhdpi
      • ic_minus.png, ic_plus.png, camera_1.png, camera.png, floppy.png, game_controller.png, graphics_card.png, hdmi.png, headphones.png, imac.png, ipad.png, keyboard.png, laptop.png, lcd.png, light_bulb.png, mac_mini.png, monitor.png, mouse.png, movie_camera.png, music_player.png, pc.png, playstation.png, printer.png, remote.png, smart_watch.png, smartphone.png, tablet.png, usb.png, webcam.png, windows_phone.png, zerox.png
  • values
    • colors.xml - no changes in this.
    • strings.xml - no changes in this.
    • styles.xml - no changes in this.

Follow the below steps.

Step 1: Create a new blank project with an empty activity.

Step 2: Let us create resources for our app copy the appropriate and all required image files in the res\mipmap-xxxhdpi folder. For this example, we are using around 31 images, and it is available in the source code. The source code download link is available at the end of this article.

Step 3: Next, we need to create the activity_custom_listview.xml file. It is the layout file for each ListView row. ListAdapter is going to inflate activity_custom_listview.xml file for our ListView rows. We are going to create ListAdpter.java class in Step 7.

Code

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent" android:layout_margin="5dp"
    >

    <ImageView
        android:id="@+id/ivProduct"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:src="@mipmap/camera"
        android:scaleType="centerInside"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tvProductName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"

        android:gravity="center_vertical"
        android:padding="2dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/ivProduct"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tvPrice"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:gravity="center_vertical"
        android:textAppearance="?android:attr/textAppearanceLarge"
        app:layout_constraintStart_toEndOf="@+id/ivProduct"
        app:layout_constraintTop_toBottomOf="@+id/tvProductName" />


    <ImageButton
        android:id="@+id/ib_addnew"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:adjustViewBounds="true"
        android:background="#00ffffff"
        android:cropToPadding="false"
        android:scaleType="centerInside"
        android:src="@mipmap/ic_plus"
        app:layout_constraintLeft_toRightOf="@+id/tvPrice"
        app:layout_constraintStart_toEndOf="@+id/tvPrice"
        app:layout_constraintTop_toBottomOf="@+id/tvProductName" />

    <EditText
        android:id="@+id/editTextQuantity"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="0"
        android:inputType="number"
        app:layout_constraintEnd_toStartOf="@+id/ib_remove"
        app:layout_constraintStart_toEndOf="@+id/ib_addnew"
        app:layout_constraintTop_toBottomOf="@+id/tvProductName"
        app:layout_constraintLeft_toRightOf="@+id/ib_addnew"
        android:layout_marginLeft="8dp"
        app:layout_constraintRight_toLeftOf="@+id/ib_remove"
        android:layout_marginRight="8dp" />


    <ImageButton
        android:id="@+id/ib_remove"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="bottom"
        android:layout_marginTop="8dp"
        android:scaleType="centerInside"
        android:background="#00ffffff"
        android:src="@mipmap/ic_minus"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvProductName"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent" />


</android.support.constraint.ConstraintLayout>

Step 4: Let’s modify our main layout file. In our main layout activity_main.xml, we are going to remove existing items and going to add a ListView and a Place Order button. Update the content of the activity_main.xml file.

Code

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context="com.vlemonn.vlog.listviewedittextbutton.MainActivity">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Place Order"
            android:id="@+id/btnPlaceOrder"
            />
    </LinearLayout>

    <ListView
        android:id="@+id/customListView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/linearLayout" />

</android.support.constraint.ConstraintLayout>

Step 5: We need to create a Product class to store product name, price and image. We are also going to add CartQuantity in our Product Class. CartQuantity is used to product quantity selected by the user. Based on the cart quantity value, we are going to PlaceOrder. Create a new class Products.java

Code

package com.vlemonn.vlog.listviewedittextbutton;

/**
 * Created by Mayank Sanghvi on 25-11-2017.
 */

public class Product {
    String ProductName;
    Double ProductPrice;
    int    ProductImage;
    int    CartQuantity=0;

    public Product(String productName, Double productPrice, int productImage) {
        ProductName = productName;
        ProductPrice = productPrice;
        ProductImage = productImage;
    }

}

Step 6: List view holder class is for storing the inflated view components of activity_custom_listview.xml. We are storing list view holder in the row. It helps us to avoid reinitializing the view components of activity_custom_listview.xml. Create a new class for holding our Custom ListView layout view components ListViewHolder.java

Code

package com.vlemonn.vlog.listviewedittextbutton;

import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * Created by Mayank Sanghvi on 25-11-2017.
 */

public class ListViewHolder {

    TextView tvProductName ;
    ImageView ivProduct;
    TextView tvPrice;
    ImageButton btnPlus;
    EditText edTextQuantity;
    ImageButton btnMinus;
    LinearLayout llMainRow;
}

Step 7: Finally, it’s time to create a list view adapter. Adapter act as a bridge between our ListView (or UI components) and data source to fill data into our ListView (or UI Components). Create a new Java Class for our custom ListView Adapter ListAdapter.java

Code

package com.vlemonn.vlog.listviewedittextbutton;

import android.content.Context;
import android.content.res.TypedArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by Mayank Sanghvi on 25-11-2017.
 */

public class ListAdapter extends BaseAdapter {

    public ArrayList<Product> listProducts;
    private Context context;

    public ListAdapter(Context context,ArrayList<Product> listProducts) {
        this.context = context;
        this.listProducts = listProducts;
    }

    @Override
    public int getCount() {
        return listProducts.size();
    }

    @Override
    public Product getItem(int position) {
        return listProducts.get(position);
    }

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

    @Override
    public View getView(final int position, View convertView
            , ViewGroup parent) {
        View row;
        final ListViewHolder listViewHolder;
        if(convertView == null)
        {
            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = layoutInflater.inflate(R.layout.activity_custom_listview,parent,false);
            listViewHolder = new ListViewHolder();
            listViewHolder.tvProductName = row.findViewById(R.id.tvProductName);
            listViewHolder.ivProduct = row.findViewById(R.id.ivProduct);
            listViewHolder.tvPrice = row.findViewById(R.id.tvPrice);
            listViewHolder.btnPlus = row.findViewById(R.id.ib_addnew);
            listViewHolder.edTextQuantity = row.findViewById(R.id.editTextQuantity);
            listViewHolder.btnMinus = row.findViewById(R.id.ib_remove);
            row.setTag(listViewHolder);
        }
        else
        {
            row=convertView;
            listViewHolder= (ListViewHolder) row.getTag();
        }
        final Product products = getItem(position);

        listViewHolder.tvProductName.setText(products.ProductName);
        listViewHolder.ivProduct.setImageResource(products.ProductImage);
        listViewHolder.tvPrice.setText(products.ProductPrice+" $");
        listViewHolder.edTextQuantity.setText(products.CartQuantity+"");
        listViewHolder.btnPlus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                updateQuantity(position,listViewHolder.edTextQuantity,1);
            }
        });
        //listViewHolder.edTextQuantity.setText("0");
        listViewHolder.btnMinus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateQuantity(position,listViewHolder.edTextQuantity,-1);

            }
        });

        return row;
    }

    private void updateQuantity(int position, EditText edTextQuantity, int value) {

        Product products = getItem(position);
        if(value > 0)
        {
            products.CartQuantity = products.CartQuantity + 1;
        }
        else
        {
            if(products.CartQuantity > 0)
            {
                products.CartQuantity = products.CartQuantity - 1;
            }

        }
        edTextQuantity.setText(products.CartQuantity+"");
    }
}

Step 8: Last thing we need to update our Main Activity Java Class MainActivity.java. In our MainActivity.java class, we are going to

  • Create dummy data for Products.
  • Initialize our ListView, Place Order button
  • Add a click listener to the Place Order button. 
  • Create a new instance of ListAdapter and assign it to our ListView

Code

package com.vlemonn.vlog.listviewedittextbutton;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private ListAdapter listAdapter;
    ArrayList<Product> products = new ArrayList<>();
    Button btnPlaceOrder;
    ArrayList<Product> productOrders = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getProduct();
        listView = (ListView) findViewById(R.id.customListView);
        listAdapter = new ListAdapter(this,products);
        listView.setAdapter(listAdapter);
        btnPlaceOrder = (Button) findViewById(R.id.btnPlaceOrder);
        btnPlaceOrder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                placeOrder();
            }
        });
    }

    private void placeOrder()
    {
        productOrders.clear();
        for(int i=0;i<listAdapter.listProducts.size();i++)
        {
            if(listAdapter.listProducts.get(i).CartQuantity > 0)
            {
                Product products = new Product(
                        listAdapter.listProducts.get(i).ProductName
                        ,listAdapter.listProducts.get(i).ProductPrice
                        ,listAdapter.listProducts.get(i).ProductImage
                );
                products.CartQuantity = listAdapter.listProducts.get(i).CartQuantity;
                productOrders.add(products);
            }
        }
    }

    public void getProduct() {
        products.add(new Product("Video Recorder",10.0d,R.mipmap.camera));
        products.add(new Product("Camera",11.0d,R.mipmap.camera_1));
        products.add(new Product("Floppy",12.0d,R.mipmap.floppy));
        products.add(new Product("Game Pad",13.0d,R.mipmap.game_controller));
        products.add(new Product("Graphics Card",14.0d,R.mipmap.graphics_card));
        products.add(new Product("HDMI Cable",16.0d,R.mipmap.hdmi));
        products.add(new Product("Headphones",11.0d,R.mipmap.headphones));
        products.add(new Product("I Mac",15.0d,R.mipmap.imac));
        products.add(new Product("I Pad",17.0d,R.mipmap.ipad));
        products.add(new Product("Keyboard",67.0d,R.mipmap.keyboard));
        products.add(new Product("Laptop",41.0d,R.mipmap.laptop));
        products.add(new Product("LCD",16.0d,R.mipmap.lcd));
        products.add(new Product("Light Bulb",18.0d,R.mipmap.light_bulb));
        products.add(new Product("Mac Mini",121.0d,R.mipmap.mac_mini));
        products.add(new Product("Monitor",122.0d,R.mipmap.monitor));
        products.add(new Product("Mouse",14.0d,R.mipmap.mouse));
        products.add(new Product("Movie Camera",51.0d,R.mipmap.movie_camera));
        products.add(new Product("Music Player",12.0d,R.mipmap.music_player));
        products.add(new Product("PC",16.0d,R.mipmap.pc));
        products.add(new Product("Playstation",12.0d,R.mipmap.playstation));
        products.add(new Product("Printer",17.0d,R.mipmap.printer));
        products.add(new Product("Remote",12.0d,R.mipmap.remote));
        products.add(new Product("Smart Watch",18.0d,R.mipmap.smart_watch));
        products.add(new Product("Smartphone",19.0d,R.mipmap.smartphone));
        products.add(new Product("Tablet",21.0d,R.mipmap.tablet));
        products.add(new Product("USB",87.0d,R.mipmap.usb));
        products.add(new Product("Webcam",87.0d,R.mipmap.webcam));
        products.add(new Product("Windows Phone",123.0d,R.mipmap.windows_phone));
        products.add(new Product("Zerox",85.0d,R.mipmap.zerox));
    }
}

Ok, our code is ready for execution. Save your project and execute it in AVD.

Note: If the app is failing due to the memory issue, add below inline in AndroidManifest.xml file.

Code

android:largeHeap="true"

In our next article, we are going to check How to use the Place Order Button to send data to another activity or to a web server. I hope you can use the above instruction in your android app without any issue. 
The source code is available below. You need to login to download the source code.

2 Comments
Leave A Comment

Please login to post your valuable comments.

  • ...
    Reply

    Mayank Sanghvi

    Thanks for highlighting the issue. It is fixed.

  • ...
    Reply

    ahmad baddah

    hey its empty 

Join the newsletter

Get the latest vLemonn news first

share