recyclerview send list of data to database

Hi Guys, Welcome to Proto Coders Point, So i my previous android tutorial blog post i have covered Android RecyclerView with EditText Example + Expense sum calculation

You can check the GIF Video below

Recycler View with calculating user entered expenses.

Sending Recyclerview Entered data/ array list to Database (phpmyadmin)

So Title itself says then in this part we gonna send our recyclerview entered data to our database i.e. phpmyadmin database.

I have also created a video tutorial on my youtube channel proto coders point on how to send arraylist to database. (Watch it now)

Recyclerview user entered – array list send to database

Ok So let’s begin,

Database Setup

My database is hosted with my website hosting protocoderspoint.com, so in my hosting i have created a new database special for this tutorial.

Create a new table in your phpmyadmin database

How a look at database, it has a table by name :
‘ExpenseTable’ which has 3 column

  • id : type int auto Increment.
  • ExpenseName : type varchar(50).
  • ExpenseAmt : type varchar(50).

command to create table in your database

CREATE TABLE `ExpenseTable` (
  `id` int(11) NOT NULL,
  `ExpenseName` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  `ExpenseAmt` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

So now we are done with create the database table now let’s go with php code that helps us in getting connected with database and store the array list data into the table.

Php code – connect database – storing array list to data table

Here are 2 php files/code

  • connect.php: Help us in getting connected with our database.
  • save_expense.php: Helps us in storing/inserting data into our database.

connect.php

<?php

$conn = mysqli_connect("localhost", "Login username", "Login User password", "database Name");

if($conn)
{
  //echo "Connection Success";
}
else
{
//  echo "Connection Failed";

}

?>

The connect.php is a common php code that help in getting connected with our database, I have created connect.php file separate so that in my other php code i can simply include connect.php code that’s it, whenever i hit or call other php code where connet.php is included it automatically get connected to out database.

save_expense.php

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);

include 'connect.php';

$expname = $_POST["expname"];
$expname = json_decode($expname,TRUE);

$amount = $_POST["expamt"];
$amount = json_decode($amount,TRUE);


for($i = 0; $i < count($expname); $i++){

      $sql = "INSERT INTO ExpenseTable (ExpenseName, ExpenseAmt) VALUES ('$expname[$i]','$amount[$i]')";

        mysqli_query($conn, $sql);
}

echo "DONE"

?>

Then, in above save_expense.php code i m sending list of jsonArray string from our android app using POST method.

Snippet code Explaination

$expname = $_POST[“expname”];
$expname = json_decode($expname,TRUE);

Here the PHP code is receiving ArrayList in the form of JSON ARRAY, that is been decoded using the json_decode function.

After that we are using for loop to iterate the total number of data present in the array list using count($expname) this will return a number, for example, suppose your array is [‘0’, ‘1’, ‘2’, ‘3’] then count will return 4, so the for loop will run for 4 times.
Then in for loop, we have a SQL query then will insert the data into our database using mysqli_query.

Ok so now we are done with our php script that will insert data into our database, now let’s go to android coding.

Android Coding –

Recyclerview EditText Entered data store in an array and send to database

android project structure

Have a look at my android project structure for easy understanding of the android tutorial on Recyclerview with editText Field.

android recyclerview

Check out this tutorial article “Android RecyclerView with EditText Example + Expense sum calculation” to know the UI and the calculation part and how i store user entered data in arraylist.

Android Volley library is been used to send data from android to php

build.gradle (module: app) 
under dependencies section add the volley library.
implementation 'com.android.volley:volley:1.1.0'

itemdatamodel.java

Our DataModel class holder 2 kinds of datatype i.e integer and a string.
integer to hold Expense Id and String that holds ExpenseName.

package com.example.recyclerview_image_pick.datamodel;

public class ItemDatamodel {

    int ExpenseId;
    String ExpenseName;

    public ItemDatamodel(int expenseId, String expenseName) {
        ExpenseId = expenseId;
        ExpenseName = expenseName;
    }

    public int getExpenseId() {
        return ExpenseId;
    }

    public String getExpenseName() {
        return ExpenseName;
    }
}

MainActivity.java

Here i have created static data, and sending it to our Adapter to display the data in our android recyclerview.

package com.example.recyclerview_image_pick;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.util.Log;

import com.example.recyclerview_image_pick.Adapter.Adapter;
import com.example.recyclerview_image_pick.datamodel.ItemDatamodel;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static ArrayList<ItemDatamodel> data;
    ItemDatamodel itemDatamodel;
    // list of Expensesname
    String[] Expensesname = {"Rent","Coffee","Lunch","Dinner","Transport","Other"};

    private static RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private static RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view_expenses);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        data = new ArrayList<>();

        // generate ArrayList and store in data model
        for(int i =0;i<Expensesname.length;i++){
            itemDatamodel = new ItemDatamodel(
                    i,
                    Expensesname[i]
            );
            data.add(itemDatamodel);
        }

       // call Adapter class by passing ArrayList data
        adapter = new Adapter(data);
        // set adapter to recyclerview
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
}

activity_main.xml

android recyclerview with edittext
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_weight="0.9"
        android:id="@+id/my_recycler_view_expenses"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />
    
    <LinearLayout
        android:background="#A7B4FF"
        android:padding="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Total Expenses ₹ 0.00 "
                android:textSize="20sp"
                android:textStyle="italic"
                android:id="@+id/totalExpense"
                android:layout_gravity="center"/>

            <Button
                android:id="@+id/saveexpenses"
                android:paddingLeft="60dp"
                android:paddingRight="60dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Save"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

Adapter.java

I recommend to watch the video tutorial to understand what is going on in below android Adapter.java class.

package com.example.recyclerview_image_pick.Adapter;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.example.recyclerview_image_pick.R;
import com.example.recyclerview_image_pick.datamodel.ItemDatamodel;

import org.json.JSONArray;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {

    View rootView;
    Context context;
    private ArrayList<ItemDatamodel> dataSet;
    ArrayList<String> ExpNameArray = new ArrayList<String>();
    ArrayList<String> ExpAmtArray = new ArrayList<String>();
    boolean isOnTextChanged = false;
    int ExpenseFinalTotal = 0;
    TextView textviewTotalExpense;
    Button saveExpense;
    String SubmitExpenseURL ="https://protocoderspoint.com/php/save_expense.php";
    //constructor with dataSet passed from MainActivity when Adapter is called
    public Adapter(ArrayList<ItemDatamodel> dataSet) {
        this.dataSet = dataSet;
    }

    //Recyclerview ViewHolder
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView expensesName;
        EditText expHeld;
        Button imageButton;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            // finding view by view id.
            expensesName = (TextView) itemView.findViewById(R.id.textViewExpName);
            expHeld = (EditText) itemView.findViewById(R.id.ExpHeld);
            imageButton = (Button) itemView.findViewById(R.id.ExpBimageSelect);
        }
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        // Initialize view for recyclerview
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_prod_list, parent, false);

        context = parent.getContext();
        rootView = ((Activity) context).getWindow().getDecorView().findViewById(android.R.id.content);

        textviewTotalExpense = (TextView) rootView.findViewById(R.id.totalExpense);
        saveExpense =(Button)rootView.findViewById(R.id.saveexpenses);
        //attach view to MyViewHolder
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {

        //initialize the view with a view holder
        TextView expensesName = holder.expensesName;
        EditText expHeld = holder.expHeld;
        Button imageButton = holder.imageButton;
        int id = dataSet.get(position).getExpenseId();

        expensesName.setText(dataSet.get(position).getExpenseName());

        expHeld.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                isOnTextChanged = true;
            }

            @Override
            public void afterTextChanged(Editable editable) {

                if(isOnTextChanged){
                    isOnTextChanged = false;

                    try{

                        ExpenseFinalTotal = 0;

                        for (int i = 0;i<=id;i++){
                            if(i!=id){
                                ExpNameArray.add("0");
                                ExpAmtArray.add("0");
                            }else{
                                ExpAmtArray.add("0");
                                ExpNameArray.add("0");
                                ExpNameArray.set(id,dataSet.get(id).getExpenseName());
                                ExpAmtArray.set(id,editable.toString());
                            }
                        }
                        Log.d("ExpAmt",ExpAmtArray.toString());
                        Log.d("ExpName",ExpNameArray.toString());

                        for(int i = 0;i<=ExpAmtArray.size()-1;i++){
                            int tempTotalExpense = Integer.parseInt(ExpAmtArray.get(i));
                            ExpenseFinalTotal = ExpenseFinalTotal +tempTotalExpense;
                        }

                        textviewTotalExpense.setText("Total Expense : " +String.valueOf(ExpenseFinalTotal));
                    }catch (NumberFormatException e)
                    {
                        // catch is used because, when used enter value in editText and remove the value it
                        // it will trigger NumberFormatException, so to prevent it and remove data value from array ExpAmtArray
                        //then
                        // re-perform loop total expense calculation and display the total.

                        ExpenseFinalTotal = 0;
                        for (int i = 0; i <= id; i++) {
                            Log.d("TimesRemoved", " : " + i);

                            if (i == id) {
                                ExpNameArray.set(id,"0");
                                ExpAmtArray.set(id,"0");

                            }

                        }
                        Log.d("ExpAmt",ExpAmtArray.toString());
                        Log.d("ExpName",ExpNameArray.toString());

                        for(int i = 0;i<=ExpAmtArray.size()-1;i++){
                            int tempTotalExpense = Integer.parseInt(ExpAmtArray.get(i));
                            ExpenseFinalTotal = ExpenseFinalTotal +tempTotalExpense;
                        }

                        textviewTotalExpense.setText("Total Expense : " +String.valueOf(ExpenseFinalTotal));

                    }
                }

            }
        });


        saveExpense.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ArrayList<String> FExpenseAmtArray = new ArrayList<>();
                ArrayList<String> FExpenseNameArray = new ArrayList<>();

                if(!ExpAmtArray.isEmpty()){
                    for(int i =0 ; i<ExpAmtArray.size();i++){
                        if(!ExpAmtArray.get(i).equals("0") && !ExpAmtArray.get(i).equals("")){
                            FExpenseAmtArray.add(ExpAmtArray.get(i));
                            FExpenseNameArray.add(ExpNameArray.get(i));
                        }
                    }

                }

                Log.d("ArrayExpName",FExpenseNameArray.toString());
                Log.d("ArrayExpAmt",FExpenseAmtArray.toString());

                JSONArray jsonArrayName = new JSONArray();
                for(String Expname : FExpenseNameArray){
                    jsonArrayName.put(Expname);
                }

                JSONArray jsonArrayExpAmt = new JSONArray();
                for(String ExpAmt : FExpenseAmtArray){
                    jsonArrayExpAmt.put(ExpAmt);
                }

                SubmitExpenseData(jsonArrayName.toString(),jsonArrayExpAmt.toString());
            }
        });


    }

    private void SubmitExpenseData(String ExpName, String ExpAmt)
    {
        StringRequest stringRequest = new StringRequest(Request.Method.POST,SubmitExpenseURL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //we get the successful in String response
                        Log.e("response", response);


                    }

                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("sellresponseerror", ""+error.toString());


            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();

                params.put("expname", ExpName);
                params.put("expamt", ExpAmt);

                return params;
            }
        };
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        requestQueue.add(stringRequest);
    }



    @Override
    public int getItemCount() {
        return dataSet.size();
    }

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

    @Override
    public int getItemViewType(int position) {
        return position;
    }


}

card_prod_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:tag="cards main container">

    <androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        card_view:cardBackgroundColor="#ffffff"
        card_view:cardUseCompatPadding="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="horizontal"
            android:weightSum="2">

            <TextView
                android:id="@+id/textViewExpName"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="left|center"
                android:layout_weight="1"
                android:paddingLeft="5dp"
                android:text="Product"
                android:textStyle="italic|bold"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#000000"
                android:textSize="16sp" />

            <EditText
                android:id="@+id/ExpHeld"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:backgroundTint="#000000"
                android:gravity="center"
                android:hint="Value"
                android:inputType="number"
                android:textColor="#000000"
                android:textColorHint="#989898"
                android:textSize="14sp" />


            <Button
                android:id="@+id/ExpBimageSelect"
                android:layout_width="0dp"
                android:visibility="gone"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Select Image"
                android:textSize="6dp" />

        </LinearLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

Network Security Config

So as we are making internet call to send data to our database, we need to specify which domain or IP we are using to send/receive data, so for that, you need to create a networksecurityconfig.xml file in res>xml>

create a directory “XML” inside res then create an XML resource file networksecurityconfig.xml under that directory and copy-paste the below code.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">protocoderspoint.com</domain>  // Here replace with your domain/IP

    </domain-config>
</network-security-config>

Then go to your AndroidManifest.xml and add the network SecurityConfig file under <application> tag

 <application
        android:networkSecurityConfig="@xml/network_conf"
        android:usesCleartextTraffic="true"

/>

1 Comment