Expense Manager or Expense Tracker app
Since it is our first blog, we'll begin with a basic app i.e., an expense manager app.
As the name suggests, the app will be used for keeping track of your expenses so that you can manage your earnings.
Note: This project is built in Android Studio using Java and for backend we use SQLite.
This is the preview of the application.
To begin with we'll first design the layout.
Source Code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
android:label="@string/app_name"
tools:context=".MainActivity">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="*"
tools:layout_editor_absoluteX="157dp"
tools:layout_editor_absoluteY="412dp">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
>
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/piechart"
android:layout_width="370dp"
android:layout_height="300dp"
android:layout_margin="10dp"
android:layout_weight="1"
/>
</TableRow>
<TableRow
>
<ImageButton
android:id="@+id/incomebtn"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_margin="2dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/incomejpg" />
<ImageButton
android:id="@+id/expensebtn"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_margin="2dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/expense" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/inctransbtn"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_margin="2dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/irecord" />
<ImageButton
android:id="@+id/exptransbtn"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_margin="2dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/erecord" />
</TableRow>
</TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_income.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".Income">
<Button
android:id="@+id/buttonsave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="133dp"
android:layout_marginLeft="133dp"
android:layout_marginEnd="191dp"
android:layout_marginRight="191dp"
android:layout_marginBottom="36dp"
android:text="Save"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/occp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="17dp"
android:layout_marginLeft="17dp"
android:layout_marginTop="206dp"
android:ems="10"
android:inputType="textPersonName"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/Salaryamt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="90dp"
android:ems="10"
android:inputType="number"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/dtselect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="312dp"
android:ems="10"
android:hint="Select a Date"
android:inputType="textPersonName"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/dateid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="17dp"
android:layout_marginLeft="17dp"
android:layout_marginTop="272dp"
android:text="Date"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/Occup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="167dp"
android:text="Source of Income"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/Salaryid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="43dp"
android:text="Income"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".Expense">
<Button
android:id="@+id/buttonsv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="148dp"
android:layout_marginLeft="148dp"
android:layout_marginTop="487dp"
android:layout_marginEnd="175dp"
android:layout_marginRight="175dp"
android:text="Save"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editcatg"
android:layout_width="248dp"
android:layout_height="58dp"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
android:layout_marginTop="244dp"
android:inputType="textPersonName"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editdate"
android:layout_width="233dp"
android:layout_height="52dp"
android:layout_marginStart="44dp"
android:layout_marginLeft="44dp"
android:layout_marginTop="392dp"
android:inputType="textPersonName"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editAmt"
android:layout_width="254dp"
android:layout_height="58dp"
android:layout_marginStart="31dp"
android:layout_marginLeft="31dp"
android:layout_marginTop="101dp"
android:inputType="number"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="44dp"
android:layout_marginLeft="44dp"
android:layout_marginTop="352dp"
android:text="Date"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textcatg"
android:layout_width="143dp"
android:layout_height="35dp"
android:layout_marginStart="35dp"
android:layout_marginLeft="35dp"
android:layout_marginTop="190dp"
android:text="Category"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textExp"
android:layout_width="120dp"
android:layout_height="26dp"
android:layout_marginStart="29dp"
android:layout_marginLeft="29dp"
android:layout_marginTop="50dp"
android:text="Expense"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Add the following:
MainActivity.java
package com.example.expensemanager;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Color;
import android.widget.ImageButton;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener.*;
import android.content.Context.*;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.utils.ColorTemplate;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
PieChart pieChart;
String[] salaryList;
String[] expList;
Integer totSal=0;
Integer totExp=0;
Integer displayRem;
private ImageButton inctransbtn;
private ImageButton exptransbtn;
public static final String DATABASE_NAME="Goals.db";
public static final String TABLE_NAME="Income_table";
public static final String COL1="SALARY";
public static final String COL2="OCCUPATION";
public static final String COL3="DATE";
public static final String TABLE_name="Expense_table";
public static final String cols1="EXPENSE";
public static final String cols2="CATEGORY";
public static final String cols3="DATEEXP";
DatabaseHelper dbHelper=null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DatabaseHelper(this);
dbHelper.getWritableDatabase();
//Income records
inctransbtn=(ImageButton) findViewById(R.id.inctransbtn);
exptransbtn=(ImageButton) findViewById(R.id.exptransbtn);
//Income button
ImageButton incomeadd = (ImageButton) findViewById(R.id.incomebtn);
incomeadd.setOnClickListener(new View.OnClickListener(){
// When the button is pressed/clicked, it will run the code below
@Override
public void onClick(View view){
// Intent is what you use to start another activity
Intent intent = new Intent(MainActivity.this, Income.class);
startActivity(intent);
}
});
//Expense button
ImageButton expadd = (ImageButton) findViewById(R.id.expensebtn);
expadd.setOnClickListener(new View.OnClickListener(){
// When the button is pressed/clicked, it will run the code below
@Override
public void onClick(View view){
// Intent is what you use to start another activity
Intent intent = new Intent(MainActivity.this, Expense.class);
startActivity(intent);
}
});
pieChart=(PieChart) findViewById(R.id.piechart);
pieChart.setUsePercentValues(false);
pieChart.setExtraOffsets(5,5,5,5);
pieChart.setDragDecelerationFrictionCoef(0.95f);
pieChart.setDrawHoleEnabled(true);
pieChart.setHoleColor(Color.WHITE);
pieChart.setTransparentCircleRadius(61f);
pieChart.getLegend().setEnabled(false);
pieChart.getDescription().setEnabled(false);
String salList[]=getAllSalary();
String expenseList[]=getAllExpenses();
ArrayList<PieEntry> sal=new ArrayList<>();
//total salary
for(int i=0;i<salList.length;i++)
{
totSal=totSal+(Integer.parseInt(salList[i]));
}
//total expenses
for(int i=0;i<expenseList.length;i++)
{
totExp=totExp+(Integer.parseInt(expenseList[i]));
}
displayRem=totSal-totExp;
sal.add(new PieEntry(displayRem));
sal.add(new PieEntry(totExp));
PieDataSet dataSet=new PieDataSet(sal,"Income");
dataSet.setSliceSpace(3f);
dataSet.setSelectionShift(5f);
dataSet.setColors(ColorTemplate.JOYFUL_COLORS);
PieData data=new PieData(dataSet);
data.setValueTextSize(10f);
data.setValueTextColor(Color.YELLOW);
pieChart.setData(data);
ViewIncome();
ViewExpense();
}
//get Salaries
public String[] getAllSalary()
{
int i=0;
String selectQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db=openOrCreateDatabase("Goals.db", MODE_PRIVATE, null);
Cursor cursor=db.rawQuery(selectQuery,null);
int count=cursor.getCount();
salaryList=new String[count];
if(cursor.moveToFirst())
{
do {
salaryList[i]=cursor.getString(0);
i++;
}while (cursor.moveToNext());
}
return salaryList;
}
//get expenses
public String[] getAllExpenses()
{
int i=0;
String selectQuery="SELECT * FROM "+ TABLE_name;
SQLiteDatabase db=openOrCreateDatabase("Goals.db", MODE_PRIVATE, null);
Cursor cursor=db.rawQuery(selectQuery,null);
int count=cursor.getCount();
expList=new String[count];
if(cursor.moveToFirst())
{
do {
expList[i]=cursor.getString(0);
i++;
}while (cursor.moveToNext());
}
return expList;
}
@Override
public void onRestart()
{
super.onRestart();
finish();
startActivity(getIntent());
}
//view income
public void ViewIncome()
{
inctransbtn.setOnClickListener(new View.OnClickListener(){
// When the button is pressed/clicked, it will run the code below
public void onClick(View view) {
Cursor data=dbHelper.showData();
if(data.getCount()==0)
{
//message
display("Error","No Data Found.");
return;
}
StringBuffer buffer=new StringBuffer();
while (data.moveToNext())
{
buffer.append("\n"+"Income: " + data.getString(0) + "\n");
buffer.append("Source: " + data.getString(1) + "\n");
buffer.append("Date: " + data.getString(2) + "\n");
display("All Income: ", buffer.toString());
}
}
});
}
//view expense
public void ViewExpense()
{
exptransbtn.setOnClickListener(new View.OnClickListener(){
// When the button is pressed/clicked, it will run the code below
public void onClick(View view) {
Cursor data=dbHelper.showExpData();
if(data.getCount()==0)
{
//message
display("Error","No Data Found.");
return;
}
StringBuffer buffer=new StringBuffer();
while (data.moveToNext())
{
buffer.append("\n"+"Expense: " + data.getString(0) + "\n");
buffer.append("Category: " + data.getString(1) + "\n");
buffer.append("Date: " + data.getString(2) + "\n");
display("All Expenses: ", buffer.toString());
}
}
});
}
public void display(String title,String message)
{
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(message);
builder.show();
}
}
Income.java
package com.example.expensemanager;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class Income extends AppCompatActivity {
TextView dateid;
EditText dtselect;
DatabaseHelper GoalsDB;
Button btnsave;
EditText sal,occ,dt;
DatePickerDialog.OnDateSetListener setListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_income);
dateid=findViewById(R.id.dateid);
dtselect=findViewById(R.id.dtselect);
Calendar calendar=Calendar.getInstance();
final int year=calendar.get(Calendar.YEAR);
final int month=calendar.get(Calendar.MONTH);
final int day=calendar.get(Calendar.DAY_OF_MONTH);
dtselect.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
DatePickerDialog datePickerDialog=new DatePickerDialog(
Income.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
month=month+1;
String date=day+"/"+month+"/"+year;
dtselect.setText(date);
}
},year,month,day);
datePickerDialog.show();
}
});
GoalsDB=new DatabaseHelper(this);
sal=(EditText) findViewById(R.id.Salaryamt);
occ=(EditText) findViewById(R.id.occp);
dt=(EditText) findViewById(R.id.dtselect);
btnsave=(Button) findViewById(R.id.buttonsave);
AddData();
}
public void AddData()
{
btnsave.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String salary=sal.getText().toString();
String occp=occ.getText().toString();
String dated=dt.getText().toString();
boolean insertData=GoalsDB.addData(salary,occp,dated);
if(insertData==true)
{
Toast.makeText(Income.this,"Data Successfully Inserted",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(Income.this,"Something went wrong!",Toast.LENGTH_LONG).show();
}
sal.setText("");
occ.setText("");
dt.setText("");
}
});
}
}Expense.java
package com.example.expensemanager;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Calendar;
public class Expense extends AppCompatActivity {
TextView textdate;
EditText editdate;
DatabaseHelper GoalsDB;
Button btnsave;
EditText exp,cat,dt;
DatePickerDialog.OnDateSetListener setListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_expense);
textdate=findViewById(R.id.textdate);
editdate=findViewById(R.id.editdate);
Calendar calendar=Calendar.getInstance();
final int year=calendar.get(Calendar.YEAR);
final int month=calendar.get(Calendar.MONTH);
final int day=calendar.get(Calendar.DAY_OF_MONTH);
editdate.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
DatePickerDialog datePickerDialog=new DatePickerDialog(
Expense.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
month=month+1;
String date=day+"/"+month+"/"+year;
editdate.setText(date);
}
},year,month,day);
datePickerDialog.show();
}
});
GoalsDB=new DatabaseHelper(this);
exp=(EditText) findViewById(R.id.editAmt);
cat=(EditText) findViewById(R.id.editcatg);
dt=(EditText) findViewById(R.id.editdate);
btnsave=(Button) findViewById(R.id.buttonsv);
ExpAdd();
}
public void ExpAdd()
{
btnsave.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String expense=exp.getText().toString();
String category=cat.getText().toString();
String dated=dt.getText().toString();
boolean insertData=GoalsDB.expAdd(expense,category,dated);
if(insertData==true)
{
Toast.makeText(Expense.this,"Data Successfully Inserted",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(Expense.this,"Something went wrong!",Toast.LENGTH_LONG).show();
}
exp.setText("");
cat.setText("");
dt.setText("");
}
});
}
}
package com.example.expensemanager;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME="Goals.db";
public static final String TABLE_NAME="Income_table";
public static final String COL1="SALARY";
public static final String COL2="OCCUPATION";
public static final String COL3="DATE";
public static final String TABLE_name="Expense_table";
public static final String cols1="EXPENSE";
public static final String cols2="CATEGORY";
public static final String cols3="DATEEXP";
public DatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable="CREATE TABLE " + TABLE_NAME + " (SALARY INTEGER, " + " OCCUPATION TEXT, DATE TEXT )";
String cTable="CREATE TABLE " + TABLE_name + " (EXPENSE INTEGER, " + " CATEGORY TEXT, DATEEXP TEXT )";
db.execSQL(createTable);
db.execSQL(cTable);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
String query1,query2;
query1 = " DROP TABLE IF EXISTS Income_table ";
query2=" DROP TABLE IF EXISTS Expense_table ";
sqLiteDatabase.execSQL(query1);
sqLiteDatabase.execSQL(query2);
onCreate(sqLiteDatabase);
}
public boolean addData(String salary, String occp, String dated )
{
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put(COL1,salary);
contentValues.put(COL2,occp);
contentValues.put(COL3,dated);
long result=db.insert(TABLE_NAME,null,contentValues);
if(result==-1)
{
return false;
}
else
{
return true;
}
}
public boolean expAdd(String exp,String catg,String doe)
{
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put(cols1,exp);
contentValues.put(cols2,catg);
contentValues.put(cols3,doe);
long result=db.insert(TABLE_name,null,contentValues);
if(result==-1)
{
return false;
}
else
{
return true;
}
}
//Income
public Cursor showData()
{
SQLiteDatabase db=this.getWritableDatabase();
Cursor data=db.rawQuery("SELECT * FROM " + TABLE_NAME,null);
return data;
}
//Expense
public Cursor showExpData()
{
SQLiteDatabase db=this.getWritableDatabase();
Cursor data=db.rawQuery("SELECT * FROM " + TABLE_name,null);
return data;
}
}
Add images of your choice on the ImageButton. Create an icon image. And your app is ready to perform.
Comments
Post a Comment