MainActivity.java
package org.meicode.meibank;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.meicode.meibank.Adapters.TransactionAdapter;
import org.meicode.meibank.Authentication.LoginActivity;
import org.meicode.meibank.Database.DatabaseHelper;
import org.meicode.meibank.Dialogs.AddTransactionDialog;
import org.meicode.meibank.Models.Transaction;
import org.meicode.meibank.Models.User;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private static final String TAG = “MainActivity”;
private BottomNavigationView bottomNavigationView;
private TextView txtAmount, txtWelcome;
private RecyclerView transactionRecView;
private BarChart barChart;
private LineChart lineChart;
private FloatingActionButton fbAddTransaction;
private Toolbar toolbar;
private Utils utils;
private DatabaseHelper databaseHelper;
private GetAccountAmount getAccountAmount;
private GetTransactions getTransactions;
private GetProfit getProfit;
private TransactionAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initBottomNavView();
setSupportActionBar(toolbar);
utils = new Utils(this);
User user = utils.isUserLoggedIn();
if (null != user) {
Toast.makeText(this, “User: ” + user.getFirst_name() + ” logged in”, Toast.LENGTH_SHORT).show();
}else {
Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
databaseHelper = new DatabaseHelper(this);
setupAmount();
setOnClickListeners();
initTransactionRecView();
initLineChart();
}
private void initLineChart() {
Log.d(TAG, “initLineChart: started”);
//TODO: execute
getProfit = new GetProfit();
User user = utils.isUserLoggedIn();
if (null != user) {
getProfit.execute(user.get_id());
}
}
private void initTransactionRecView() {
Log.d(TAG, “initTransactionRecView: started”);
adapter = new TransactionAdapter();
transactionRecView.setAdapter(adapter);
transactionRecView.setLayoutManager(new LinearLayoutManager(this));
getTransactions();
}
private void getTransactions() {
Log.d(TAG, “getTransactions: started”);
getTransactions = new GetTransactions();
User user = utils.isUserLoggedIn();
if (null != user) {
getTransactions.execute(user.get_id());
}
}
private void setOnClickListeners() {
Log.d(TAG, “setOnClickListeners: started”);
txtWelcome.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this)
.setTitle(“Mei Bank”)
.setMessage(“Created and Developed By Meisam at MeiCode.org”)
.setNegativeButton(“Dismiss”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).setPositiveButton(“Visit”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(MainActivity.this, WebsiteActivity.class);
startActivity(intent);
}
});
builder.show();
}
});
fbAddTransaction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AddTransactionDialog addTransactionDialog = new AddTransactionDialog();
addTransactionDialog.show(getSupportFragmentManager(), “add transaction dialog”);
}
});
}
@Override
protected void onResume() {
super.onResume();
setupAmount();
getTransactions();
initLineChart();
}
@Override
protected void onStart() {
super.onStart();
setupAmount();
getTransactions();
initLineChart();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != getTransactions) {
if (!getTransactions.isCancelled()) {
getTransactions.cancel(true);
}
}
if (null != getAccountAmount) {
if (!getAccountAmount.isCancelled()) {
getAccountAmount.cancel(true);
}
}
if (null != getProfit) {
if (!getProfit.isCancelled()) {
getProfit.cancel(true);
}
}
}
private void setupAmount() {
Log.d(TAG, “setupAmount: started”);
User user = utils.isUserLoggedIn();
if (null != user) {
getAccountAmount = new GetAccountAmount();
getAccountAmount.execute(user.get_id());
}
}
private class GetAccountAmount extends AsyncTask<Integer, Void, Double> {
@Override
protected Double doInBackground(Integer… integers) {
try{
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(“users”, new String[] {“remained_amount”}, “_id=?”,
new String[] {String.valueOf(integers[0])}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
double amount = cursor.getDouble(cursor.getColumnIndex(“remained_amount”));
cursor.close();
db.close();
return amount;
}else {
cursor.close();
db.close();
return null;
}
}else {
db.close();
return null;
}
}catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(Double aDouble) {
super.onPostExecute(aDouble);
if (null != aDouble) {
txtAmount.setText(String.valueOf(aDouble) + ” $”);
}else {
txtAmount.setText(“0.0 $”);
}
}
}
private class GetTransactions extends AsyncTask<Integer, Void, ArrayList<Transaction>> {
@Override
protected ArrayList<Transaction> doInBackground(Integer… integers) {
try {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(“transactions”, null, “user_id=?”,
new String[] {String.valueOf(integers[0])}, null, null, “date”);
if (null != cursor) {
if (cursor.moveToFirst()) {
ArrayList<Transaction> transactions = new ArrayList<>();
for (int i=0; i<cursor.getCount(); i++) {
Transaction transaction = new Transaction();
transaction.set_id(cursor.getInt(cursor.getColumnIndex(“_id”)));
transaction.setAmount(cursor.getDouble(cursor.getColumnIndex(“amount”)));
transaction.setDate(cursor.getString(cursor.getColumnIndex(“date”)));
transaction.setDescription(cursor.getString(cursor.getColumnIndex(“description”)));
transaction.setRecipient(cursor.getString(cursor.getColumnIndex(“recipient”)));
transaction.setType(cursor.getString(cursor.getColumnIndex(“type”)));
transaction.setUser_id(cursor.getInt(cursor.getColumnIndex(“user_id”)));
transactions.add(transaction);
cursor.moveToNext();
}
cursor.close();
db.close();
return transactions;
}else {
cursor.close();
db.close();
return null;
}
}else {
db.close();
return null;
}
}catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(ArrayList<Transaction> transactions) {
super.onPostExecute(transactions);
if (null != transactions) {
adapter.setTransactions(transactions);
}else {
adapter.setTransactions(new ArrayList<Transaction>());
}
}
}
private class GetProfit extends AsyncTask<Integer, Void, ArrayList<Transaction>> {
@Override
protected ArrayList<Transaction> doInBackground(Integer… integers) {
try {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(“transactions”, null, “user_id=? AND type=?”,
new String[] {String.valueOf(integers[0]), “profit”}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
ArrayList<Transaction> transactions = new ArrayList<>();
for (int i=0; i<cursor.getCount(); i++) {
Transaction transaction = new Transaction();
transaction.set_id(cursor.getInt(cursor.getColumnIndex(“_id”)));
transaction.setAmount(cursor.getDouble(cursor.getColumnIndex(“amount”)));
transaction.setDate(cursor.getString(cursor.getColumnIndex(“date”)));
transaction.setDescription(cursor.getString(cursor.getColumnIndex(“description”)));
transaction.setRecipient(cursor.getString(cursor.getColumnIndex(“recipient”)));
transaction.setType(cursor.getString(cursor.getColumnIndex(“type”)));
transaction.setUser_id(cursor.getInt(cursor.getColumnIndex(“user_id”)));
transactions.add(transaction);
cursor.moveToNext();
}
cursor.close();
db.close();
return transactions;
}else {
cursor.close();
db.close();
return null;
}
}else {
db.close();
return null;
}
}catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(ArrayList<Transaction> transactions) {
super.onPostExecute(transactions);
if (null != transactions) {
ArrayList<Entry> entries = new ArrayList<>();
for (Transaction t: transactions) {
try {
Date date = new SimpleDateFormat(“yyyy-MM-dd”).parse(t.getDate());
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
calendar.setTime(date);
int month= calendar.get(Calendar.MONTH)+1;
Log.d(TAG, “onPostExecute: month: ” + month);
if (calendar.get(Calendar.YEAR) == year) {
boolean doesMonthExist =false;
for (Entry e: entries) {
if (e.getX()==month) {
doesMonthExist = true;
}else {
doesMonthExist = false;
}
}
if (!doesMonthExist) {
entries.add(new Entry(month, (float) t.getAmount()));
}else {
for (Entry e: entries) {
if (e.getX() == month) {
e.setY(e.getY() + (float) t.getAmount());
}
}
}
}
} catch (ParseException e) {
e.printStackTrace();
}
}
LineDataSet dataSet = new LineDataSet(entries, “Profit chart”);
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSet.setDrawFilled(true);
LineData data = new LineData(dataSet);
XAxis xAxis = lineChart.getXAxis();
xAxis.setEnabled(false);
YAxis yAxis = lineChart.getAxisRight();
yAxis.setEnabled(false);
YAxis leftAxis = lineChart.getAxisLeft();
leftAxis.setDrawGridLines(false);
// Description description = new Description();
// description.setText(“Descriiiiiiption”);
lineChart.setDescription(null);
lineChart.setData(data);
}else {
Log.d(TAG, “onPostExecute: transactions array list was null”);
}
}
}
private void initBottomNavView() {
Log.d(TAG, “initBottomNavView: started”);
bottomNavigationView.setSelectedItemId(R.id.menu_item_home);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.menu_item_stats:
//TODO: complete this logic
break;
case R.id.menu_item_transaction:
break;
case R.id.menu_item_home:
break;
case R.id.menu_item_loan:
break;
case R.id.menu_item_investment:
break;
default:
break;
}
return false;
}
});
}
private void initViews() {
Log.d(TAG, “initViews: started”);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavView);
txtAmount = (TextView)findViewById(R.id.txtAmount);
txtWelcome = (TextView) findViewById(R.id.txtWelcome);
transactionRecView = (RecyclerView) findViewById(R.id.transactionRecView);
barChart = (BarChart) findViewById(R.id.dailySpentChart);
lineChart = (LineChart) findViewById(R.id.profitChart);
fbAddTransaction = (FloatingActionButton) findViewById(R.id.fbAddTransaction);
toolbar = (Toolbar) findViewById(R.id.toolbar);
}
}
DatabaseHelper.java
package org.meicode.meibank.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.Nullable;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = “DatabaseHelper”;
private static final String DB_NAME = “fb_mei_bank”;
private static final int DB_VERSION = 1;
public DatabaseHelper(@Nullable Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
Log.d(TAG, “onCreate: started”);
String createUserTable = “CREATE TABLE users (_id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL, ” +
“password TEXT NOT NULL, ” +
“first_name TEXT, last_name TEXT, address TEXT, image_url TEXT, remained_amount DOUBLE)”;
String createShoppingTable = “CREATE TABLE shopping (_id INTEGER PRIMARY KEY AUTOINCREMENT, item_id INTEGER, ” +
“user_id INTEGER, transaction_id INTEGER, price DOUBLE, date DATE, description TEXT)”;
String createInvestmentTable = “CREATE TABLE investments (_id INTEGER PRIMARY KEY AUTOINCREMENT, amount DOUBLE, ” +
“monthly_roi DOUBLE, name TEXT, init_date DATE, finish_date DATE, user_id INTEGER, transaction_id INTEGER)”;
String createLoansTable = “CREATE TABLE loans (_id INTEGER PRIMARY KEY AUTOINCREMENT, init_date DATE, ” +
“finish_date DATE, init_amount DOUBLE, remained_amount DOUBLE, monthly_payment DOUBLE, monthly_roi DOUBLE,” +
“name TEXT, user_id INTEGER)”;
String createTransactionTable = “CREATE TABLE transactions (_id INTEGER PRIMARY KEY AUTOINCREMENT, amount double, ” +
“date DATE, type TEXT, user_id INTEGER, recipient TEXT, description TEXT)”;
String createItemsTable = “CREATE TABLE items (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, image_url TEXT,” +
“description TEXT)”;
sqLiteDatabase.execSQL(createUserTable);
sqLiteDatabase.execSQL(createShoppingTable);
sqLiteDatabase.execSQL(createInvestmentTable);
sqLiteDatabase.execSQL(createLoansTable);
sqLiteDatabase.execSQL(createTransactionTable);
sqLiteDatabase.execSQL(createItemsTable);
addInitialItems(sqLiteDatabase);
addTestTransaction(sqLiteDatabase);
addTestProfit(sqLiteDatabase);
}
private void addTestProfit(SQLiteDatabase db) {
Log.d(TAG, “addTestProfit: started”);
ContentValues firstValues = new ContentValues();
firstValues.put(“amount”, 15.0);
firstValues.put(“type”, “profit”);
firstValues.put(“date”, “2019-08-10”);
firstValues.put(“description”, “monthly profit from Bank of America”);
firstValues.put(“user_id”, 1);
firstValues.put(“recipient”, “Bank of America”);
db.insert(“transactions”, null, firstValues);
ContentValues secondValues = new ContentValues();
secondValues.put(“amount”, 25.0);
secondValues.put(“type”, “profit”);
secondValues.put(“date”, “2019-08-26”);
secondValues.put(“description”, “monthly profit from Real Estate investment”);
secondValues.put(“user_id”, 1);
secondValues.put(“recipient”, “Real Estate Agency”);
db.insert(“transactions”, null, secondValues);
ContentValues thirdValues = new ContentValues();
thirdValues.put(“amount”, 32.0);
thirdValues.put(“type”, “profit”);
thirdValues.put(“date”, “2019-07-11”);
thirdValues.put(“description”, “monthly profit stocks”);
thirdValues.put(“user_id”, 1);
thirdValues.put(“recipient”, “Vangaurd”);
db.insert(“transactions”, null, thirdValues);
}
private void addTestTransaction(SQLiteDatabase sqLiteDatabase) {
Log.d(TAG, “addTestTransaction: started”);
ContentValues values = new ContentValues();
values.put(“_id”, 0);
values.put(“amount”, 10.5);
values.put(“date”, “2019-10-04”);
values.put(“type”, “shopping”);
values.put(“user_id”, 1);
values.put(“description”, “Grocery shopping”);
values.put(“recipient”, “Walmart”);
long newTransactionId = sqLiteDatabase.insert(“transactions”, null, values);
Log.d(TAG, “addTestTransaction: transaction id: ” + newTransactionId);
}
private void addInitialItems (SQLiteDatabase db) {
Log.d(TAG, “addInitialItems: started”);
ContentValues values = new ContentValues();
values.put(“name”, “Bike”);
values.put(“image_url”, “https://cdn.shopify.com/s/files/1/0903/4494/products/Smashing-Pumpkin-GX-Eagle-complete-front-white.jpg”);
values.put(“description”, “The perfect mountain bike”);
db.insert(“items”, null, values);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
RegisterActivity.java
package org.meicode.meibank.Authentication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.meicode.meibank.Database.DatabaseHelper;
import org.meicode.meibank.MainActivity;
import org.meicode.meibank.Models.User;
import org.meicode.meibank.R;
import org.meicode.meibank.Utils;
import org.meicode.meibank.WebsiteActivity;
public class RegisterActivity extends AppCompatActivity {
private static final String TAG = “RegisterActivity”;
private EditText edtTxtEmail, edtTxtPassword, edtTxtAddress, edtTxtName;
private TextView txtWarning, txtLogin, txtLicence;
private ImageView firstImage, secondImage, thirdImage, forthImage, fifthImage;
private Button btnRegister;
private String image_url;
private DatabaseHelper databaseHelper;
private DoesUserExist doesUserExist;
private RegisterUser registerUser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
initViews();
databaseHelper = new DatabaseHelper(this);
image_url = “first”;
handleImageUrl();
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
initRegister();
}
});
txtLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
}
});
txtLicence.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(RegisterActivity.this, WebsiteActivity.class);
startActivity(intent);
}
});
}
private void handleImageUrl() {
Log.d(TAG, “handleImageUrl: started”);
firstImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
image_url = “first”;
}
});
secondImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
image_url = “second”;
}
});
thirdImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
image_url = “third”;
}
});
forthImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
image_url = “forth”;
}
});
fifthImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
image_url = “fifth”;
}
});
}
private void initRegister() {
Log.d(TAG, “initRegister: started”);
String email = edtTxtEmail.getText().toString();
String password = edtTxtPassword.getText().toString();
if (email.equals(“”) || password.equals(“”)) {
txtWarning.setVisibility(View.VISIBLE);
txtWarning.setText(“Please enter the password and Email”);
}else {
txtWarning.setVisibility(View.GONE);
doesUserExist = new DoesUserExist();
doesUserExist.execute(email);
}
}
private class DoesUserExist extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String… strings) {
try{
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(“users”, new String[] {“_id”, “email”}, “email=?”,
new String[] {strings[0]}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
if (cursor.getString(cursor.getColumnIndex(“email”)).equals(strings[0])) {
cursor.close();
db.close();
return true;
}else {
cursor.close();
db.close();
return false;
}
}else {
cursor.close();
db.close();
return false;
}
}else {
db.close();
return true;
}
}catch (SQLException e) {
e.printStackTrace();
return true;
}
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean) {
txtWarning.setVisibility(View.VISIBLE);
txtWarning.setText(“There is user with this email, please try another email”);
}else {
txtWarning.setVisibility(View.GONE);
registerUser = new RegisterUser();
registerUser.execute();
}
}
}
private class RegisterUser extends AsyncTask<Void, Void, User> {
private String email;
private String password;
private String address;
private String first_name;
private String last_name;
@Override
protected void onPreExecute() {
super.onPreExecute();
String email = edtTxtEmail.getText().toString();
String password = edtTxtPassword.getText().toString();
String address = edtTxtAddress.getText().toString();
String name = edtTxtName.getText().toString();
this.email = email;
this.password = password;
this.address = address;
String[] names = name.split(” “);
if (names.length >= 1) {
this.first_name = names[0];
for (int i=1; i<names.length; i++) {
if (i>1) {
last_name += ” ” + names[i];
}else {
last_name += names[i];
}
}
}else {
this.first_name = names[0];
}
}
@Override
protected User doInBackground(Void… voids) {
try {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(“email”, this.email);
values.put(“password”, this.password);
values.put(“address”, this.address);
values.put(“first_name”, this.first_name);
values.put(“last_name”, this.last_name);
values.put(“remained_amount”, 0.0);
values.put(“image_url”, image_url);
long userId = db.insert(“users”, null, values);
Log.d(TAG, “doInBackground: userId”);
Cursor cursor = db.query(“users”, null, “_id=?”,
new String[] {String.valueOf(userId)}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
User user = new User();
user.set_id(cursor.getInt(cursor.getColumnIndex(“_id”)));
user.setEmail(cursor.getString(cursor.getColumnIndex(“email”)));
user.setPassword(cursor.getString(cursor.getColumnIndex(“password”)));
user.setFirst_name(cursor.getString(cursor.getColumnIndex(“first_name”)));
user.setLast_name(cursor.getString(cursor.getColumnIndex(“last_name”)));
user.setImage_url(cursor.getString(cursor.getColumnIndex(“image_url”)));
user.setAddress(cursor.getString(cursor.getColumnIndex(“address”)));
user.setRemained_amount(cursor.getDouble(cursor.getColumnIndex(“remained_amount”)));
cursor.close();
db.close();
return user;
}else {
cursor.close();
db.close();
return null;
}
}else {
db.close();
return null;
}
}catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(User user) {
super.onPostExecute(user);
if (null != user) {
Toast.makeText(RegisterActivity.this, “User ” + user.getEmail() + ” registered successfully”, Toast.LENGTH_SHORT).show();
Utils utils = new Utils(RegisterActivity.this);
utils.addUserToSharedPreferences(user);
Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}else {
Toast.makeText(RegisterActivity.this, “Wasn’t able to register, please try again later”, Toast.LENGTH_SHORT).show();
}
}
}
private void initViews() {
Log.d(TAG, “initViews: called”);
edtTxtEmail = (EditText) findViewById(R.id.edtTxtEmail);
edtTxtPassword = (EditText) findViewById(R.id.edtTxtPassword);
edtTxtAddress = (EditText) findViewById(R.id.edtTxtAddress);
edtTxtName = (EditText) findViewById(R.id.edtTxtName);
txtWarning = (TextView) findViewById(R.id.txtWarning);
txtLogin = (TextView) findViewById(R.id.txtLogin);
txtLicence = (TextView) findViewById(R.id.txtLicense);
firstImage = (ImageView) findViewById(R.id.firstImage);
secondImage = (ImageView) findViewById(R.id.secondImage);
thirdImage = (ImageView) findViewById(R.id.thirdImage);
forthImage = (ImageView) findViewById(R.id.forthImage);
fifthImage = (ImageView) findViewById(R.id.fifthImage);
btnRegister = (Button) findViewById(R.id.btnRegister);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != doesUserExist) {
if (!doesUserExist.isCancelled()) {
doesUserExist.cancel(true);
}
}
if (null != registerUser) {
if (!registerUser.isCancelled()) {
registerUser.cancel(true);
}
}
}
}
LoginActivity.java
package org.meicode.meibank.Authentication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.meicode.meibank.Database.DatabaseHelper;
import org.meicode.meibank.MainActivity;
import org.meicode.meibank.Models.User;
import org.meicode.meibank.R;
import org.meicode.meibank.Utils;
import org.meicode.meibank.WebsiteActivity;
public class LoginActivity extends AppCompatActivity {
private static final String TAG = “LoginActivity”;
private EditText edtTxtEmail, edtTxtPassword;
private TextView txtWarning, txtLicense, txtRegister;
private Button btnLogin;
private DatabaseHelper databaseHelper;
private LoginUser loginUser;
private DoesEmailExist doesEmailExist;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews();
txtLicense.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(LoginActivity.this, WebsiteActivity.class);
startActivity(intent);
}
});
txtRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
initLogin();
}
});
}
private void initLogin() {
Log.d(TAG, “initLogin: started”);
if (!edtTxtEmail.getText().toString().equals(“”)){
if (!edtTxtPassword.getText().toString().equals(“”)) {
txtWarning.setVisibility(View.GONE);
//TODO: execute async task in here
doesEmailExist = new DoesEmailExist();
doesEmailExist.execute(edtTxtEmail.getText().toString());
}else {
txtWarning.setVisibility(View.VISIBLE);
txtWarning.setText(“Please enter your Password”);
}
}else {
txtWarning.setVisibility(View.VISIBLE);
txtWarning.setText(“Please enter your email address”);
}
}
private void initViews() {
Log.d(TAG, “initViews: called”);
edtTxtEmail = (EditText) findViewById(R.id.edtTxtEmail);
edtTxtPassword = (EditText) findViewById(R.id.edtTxtPassword);
txtWarning = (TextView) findViewById(R.id.txtWarning);
txtLicense = (TextView) findViewById(R.id.txtLicense);
txtRegister = (TextView) findViewById(R.id.txtRegister);
btnLogin = (Button) findViewById(R.id.btnLogin);
}
private class DoesEmailExist extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
databaseHelper = new DatabaseHelper(LoginActivity.this);
}
@Override
protected Boolean doInBackground(String… strings) {
try {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(“users”, new String[] {“email”}, “email=?”,
new String[] {strings[0]}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
cursor.close();
db.close();
return true;
}else {
cursor.close();
db.close();
return false;
}
}else {
db.close();
return false;
}
}catch (SQLException e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean) {
loginUser = new LoginUser();
loginUser.execute();
}else {
txtWarning.setVisibility(View.VISIBLE);
txtWarning.setText(“There is no such user with this email address”);
}
}
}
private class LoginUser extends AsyncTask<Void, Void, User> {
private String email;
private String password;
@Override
protected void onPreExecute() {
super.onPreExecute();
this.email = edtTxtEmail.getText().toString();
this.password = edtTxtPassword.getText().toString();
}
@Override
protected User doInBackground(Void… voids) {
try {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(“users”, null, “email=? AND password=?”,
new String[] {email, password}, null, null, null);
if (null != cursor) {
if (cursor.moveToFirst()) {
User user = new User();
user.set_id(cursor.getInt(cursor.getColumnIndex(“_id”)));
user.setEmail(cursor.getString(cursor.getColumnIndex(“email”)));
user.setPassword(cursor.getString(cursor.getColumnIndex(“password”)));
user.setFirst_name(cursor.getString(cursor.getColumnIndex(“first_name”)));
user.setLast_name(cursor.getString(cursor.getColumnIndex(“last_name”)));
user.setImage_url(cursor.getString(cursor.getColumnIndex(“image_url”)));
user.setAddress(cursor.getString(cursor.getColumnIndex(“address”)));
user.setRemained_amount(cursor.getDouble(cursor.getColumnIndex(“remained_amount”)));
cursor.close();
db.close();
return user;
}else {
cursor.close();
db.close();
return null;
}
}else {
db.close();
return null;
}
}catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(User user) {
super.onPostExecute(user);
if (null != user) {
Utils utils = new Utils(LoginActivity.this);
utils.addUserToSharedPreferences(user);
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}else {
txtWarning.setVisibility(View.VISIBLE);
txtWarning.setText(“Your password is incorrect”);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != doesEmailExist) {
if (!doesEmailExist.isCancelled()) {
doesEmailExist.cancel(true);
}
}
if (null != loginUser) {
if (!loginUser.isCancelled()) {
loginUser.cancel(true);
}
}
}
}
User.java
package org.meicode.meibank.Models;
public class User {
private int _id;
private String email;
private String password;
private String first_name;
private String last_name;
private String address;
private String image_url;
private double remained_amount;
public User(int _id, String email, String password, String first_name, String last_name, String address, String image_url, double remained_amount) {
this._id = _id;
this.email = email;
this.password = password;
this.first_name = first_name;
this.last_name = last_name;
this.address = address;
this.image_url = image_url;
this.remained_amount = remained_amount;
}
public User() {
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getImage_url() {
return image_url;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
public double getRemained_amount() {
return remained_amount;
}
public void setRemained_amount(double remained_amount) {
this.remained_amount = remained_amount;
}
@Override
public String toString() {
return “User{” +
“_id=” + _id +
“, email='” + email + ‘\” +
“, password='” + password + ‘\” +
“, first_name='” + first_name + ‘\” +
“, last_name='” + last_name + ‘\” +
“, address='” + address + ‘\” +
“, image_url='” + image_url + ‘\” +
“, remained_amount=” + remained_amount +
‘}’;
}
}
Transaction.java
package org.meicode.meibank.Models;
public class Transaction {
private int _id;
private double amount;
private String date;
private String type;
private int user_id;
private String recipient;
private String description;
public Transaction(int _id, double amount, String date, String type, int user_id, String recipient, String description) {
this._id = _id;
this.amount = amount;
this.date = date;
this.type = type;
this.user_id = user_id;
this.recipient = recipient;
this.description = description;
}
public Transaction() {
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return “Transaction{” +
“_id=” + _id +
“, amount=” + amount +
“, date='” + date + ‘\” +
“, type='” + type + ‘\” +
“, user_id=” + user_id +
“, recipient='” + recipient + ‘\” +
“, description='” + description + ‘\” +
‘}’;
}
}
Utils.java
package org.meicode.meibank;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.meicode.meibank.Authentication.RegisterActivity;
import org.meicode.meibank.Models.User;
import java.lang.reflect.Type;
public class Utils {
private static final String TAG = “Utils”;
private Context context;
public Utils(Context context) {
this.context = context;
}
public void addUserToSharedPreferences (User user) {
Log.d(TAG, “addUserToSharedPreferences: adding: ” + user.toString());
SharedPreferences sharedPreferences = context.getSharedPreferences(“logged_in_user”, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
editor.putString(“user”, gson.toJson(user));
editor.apply();
}
public User isUserLoggedIn() {
Log.d(TAG, “isUserLoggedIn: started”);
SharedPreferences sharedPreferences = context.getSharedPreferences(“logged_in_user”, Context.MODE_PRIVATE);
Gson gson = new Gson();
Type type = new TypeToken<User>(){}.getType();
return gson.fromJson(sharedPreferences.getString(“user”, null), type);
}
public void signOutUser() {
Log.d(TAG, “signOutUser: started”);
SharedPreferences sharedPreferences = context.getSharedPreferences(“logged_in_user”, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(“user”);
editor.commit();
Intent intent = new Intent(context, RegisterActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}
}
WebsiteActivity.java
package org.meicode.meibank;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebsiteActivity extends AppCompatActivity {
private static final String TAG = “WebsiteActivity”;
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_website);
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(“https://meiCode.org/”);
}
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
}else {
super.onBackPressed();
}
}
}
AddTransactionDialog.java
package org.meicode.meibank.Dialogs;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import org.meicode.meibank.R;
public class AddTransactionDialog extends DialogFragment {
private static final String TAG = “AddTransactionDialog”;
private RelativeLayout shopping, investment, loan, transaction;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_add_transaction, null);
shopping = view.findViewById(R.id.shoppingRelLayout);
investment = (RelativeLayout) view.findViewById(R.id.investmentRelLayout);
loan = (RelativeLayout) view.findViewById(R.id.loanRelLayout);
transaction = (RelativeLayout) view.findViewById(R.id.transactionRelLayout);
shopping.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO: navigate the user to the activity
}
});
investment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
loan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
transaction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(“Add Transaction”)
.setNegativeButton(“Dismiss”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).setView(view);
return builder.create();
}
}
TransactionAdapter.java
package org.meicode.meibank.Adapters;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import org.meicode.meibank.Models.Transaction;
import org.meicode.meibank.R;
import java.util.ArrayList;
public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.ViewHolder> {
private static final String TAG = “TransactionAdapter”;
private ArrayList<Transaction> transactions = new ArrayList<>();
public TransactionAdapter() {
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_transaction, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Log.d(TAG, “onBindViewHolder: called”);
holder.txtDate.setText(transactions.get(position).getDate());
holder.txtDesc.setText(transactions.get(position).getDescription());
holder.txtTransactionId.setText(String.valueOf(transactions.get(position).get_id()));
holder.txtSender.setText(transactions.get(position).getRecipient());
double amount = transactions.get(position).getAmount();
if (amount>0) {
holder.txtAmount.setText(“+ ” + amount);
holder.txtAmount.setTextColor(Color.GREEN);
}else {
holder.txtAmount.setText(“- ” + amount);
holder.txtAmount.setTextColor(Color.RED);
}
}
@Override
public int getItemCount() {
return transactions.size();
}
public void setTransactions(ArrayList<Transaction> transactions) {
this.transactions = transactions;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView txtAmount, txtDesc, txtDate, txtSender, txtTransactionId;
private CardView parent;
public ViewHolder(@NonNull View itemView) {
super(itemView);
txtAmount = (TextView) itemView.findViewById(R.id.txtAmount);
txtDesc = (TextView) itemView.findViewById(R.id.txtDesc);
txtDate = (TextView) itemView.findViewById(R.id.txtDate);
txtSender = (TextView) itemView.findViewById(R.id.txtSender);
txtTransactionId = (TextView) itemView.findViewById(R.id.txtTransaction);
parent = (CardView) itemView.findViewById(R.id.parent);
}
}
}
activity_register.xml
<?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”
tools:context=”.Authentication.RegisterActivity”>
<RelativeLayout
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerInParent=”true”>
<Button
android:id=”@+id/btnRegister”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/imagesRelLayout”
android:layout_centerHorizontal=”true”
android:layout_marginTop=”20dp”
android:background=”@color/orange”
android:text=”Register” />
<EditText
android:id=”@+id/edtTxtPassword”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/edtTxtEmail”
android:layout_marginLeft=”30dp”
android:layout_marginTop=”10dp”
android:layout_marginRight=”30dp”
android:hint=”Password”
android:inputType=”textPassword” />
<EditText
android:id=”@+id/edtTxtName”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/edtTxtPassword”
android:layout_marginLeft=”30dp”
android:layout_marginTop=”10dp”
android:layout_marginRight=”30dp”
android:hint=”Name” />
<EditText
android:id=”@+id/edtTxtAddress”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/edtTxtName”
android:layout_marginLeft=”30dp”
android:layout_marginTop=”10dp”
android:layout_marginRight=”30dp”
android:hint=”Address”
android:lines=”2″ />
<EditText
android:id=”@+id/edtTxtEmail”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/logo”
android:layout_marginLeft=”30dp”
android:layout_marginTop=”50dp”
android:layout_marginRight=”30dp”
android:hint=”Email”
android:inputType=”textEmailAddress” />
<ImageView
android:id=”@+id/logo”
android:layout_width=”100dp”
android:layout_height=”50dp”
android:layout_centerHorizontal=”true”
android:src=”@mipmap/meicode” />
<RelativeLayout
android:id=”@+id/imagesRelLayout”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/edtTxtAddress”
android:layout_centerHorizontal=”true”
android:layout_marginTop=”10dp”>
<ImageView
android:id=”@+id/firstImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:src=”@mipmap/boy” />
<ImageView
android:id=”@+id/secondImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/firstImage”
android:src=”@mipmap/girl” />
<ImageView
android:id=”@+id/thirdImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/secondImage”
android:src=”@mipmap/man” />
<ImageView
android:id=”@+id/forthImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/thirdImage”
android:src=”@mipmap/woman” />
<ImageView
android:id=”@+id/fifthImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/forthImage”
android:src=”@mipmap/secon_girl” />
</RelativeLayout>
<TextView
android:id=”@+id/txtWarning”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/btnRegister”
android:layout_centerHorizontal=”true”
android:layout_marginTop=”20dp”
android:text=”Warning”
android:textColor=”@color/colorAccent”
android:visibility=”gone” />
<TextView
android:id=”@+id/txtLogin”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/txtWarning”
android:layout_centerHorizontal=”true”
android:layout_marginTop=”20dp”
android:text=”Have an account? login from here”
android:textColor=”@color/blue” />
</RelativeLayout>
<TextView
android:id=”@+id/txtLicense”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentBottom=”true”
android:layout_centerHorizontal=”true”
android:layout_marginBottom=”10dp”
android:text=”Developed By Meisam at meiCode.org”
android:textStyle=”italic” />
</RelativeLayout>
activity_main.xml
<?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”
tools:context=”.MainActivity”>
<RelativeLayout
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:layout_below=”@+id/toolbar”
android:layout_marginBottom=”50dp”>
<androidx.core.widget.NestedScrollView
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<RelativeLayout
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<RelativeLayout
android:id=”@+id/firstRelLayout”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_marginTop=”10dp”>
<TextView
android:id=”@+id/txtWelcome”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”10dp”
android:text=”Welcome To Mei Bank”
android:textSize=”20sp”
android:textStyle=”bold” />
<TextView
android:id=”@+id/txtAmount”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_marginRight=”10dp”
android:text=”0.0 $”
android:textColor=”@color/green”
android:textSize=”20sp”
android:textStyle=”bold” />
</RelativeLayout>
<RelativeLayout
android:id=”@+id/chartRelLayout”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/firstRelLayout”
android:layout_marginTop=”10dp”>
<com.github.mikephil.charting.charts.BarChart
android:id=”@+id/dailySpentChart”
android:layout_width=”150dp”
android:layout_height=”150dp”
android:layout_alignParentRight=”true”
android:layout_marginRight=”20dp”
android:layout_toRightOf=”@+id/profitChart” />
<com.github.mikephil.charting.charts.LineChart
android:id=”@+id/profitChart”
android:layout_width=”150dp”
android:layout_height=”150dp”
android:layout_marginLeft=”20dp” />
</RelativeLayout>
<RelativeLayout
android:id=”@+id/transactionRelLayout”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/chartRelLayout”
android:layout_marginTop=”10dp”>
<TextView
android:id=”@+id/txtTransaction”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”10dp”
android:layout_marginTop=”10dp”
android:text=”Transactions”
android:textSize=”16sp”
android:textStyle=”bold” />
<androidx.recyclerview.widget.RecyclerView
android:id=”@+id/transactionRecView”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/txtTransaction”
android:layout_marginLeft=”10dp”
android:layout_marginTop=”10dp” />
</RelativeLayout>
</RelativeLayout>
</androidx.core.widget.NestedScrollView>
</RelativeLayout>
<androidx.appcompat.widget.Toolbar
android:id=”@+id/toolbar”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:background=”@drawable/background_toolbar” />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id=”@+id/bottomNavView”
android:layout_width=”match_parent”
android:layout_height=”50dp”
android:layout_alignParentBottom=”true”
android:background=”@drawable/background_toolbar”
app:menu=”@menu/bottom_nav_menu”
app:itemTextColor=”@color/bottom_nav_color”
app:itemIconTint=”@color/bottom_nav_color”/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id=”@+id/fbAddTransaction”
android:layout_width=”40dp”
android:layout_height=”40dp”
android:layout_alignParentRight=”true”
android:layout_alignParentBottom=”true”
android:layout_marginRight=”10dp”
android:layout_marginBottom=”60dp”
android:src=”@drawable/ic_add”
app:fabCustomSize=”40dp” />
</RelativeLayout>
activity_login.xml
<?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”
tools:context=”.Authentication.LoginActivity”>
<RelativeLayout
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerInParent=”true”>
<ImageView
android:layout_width=”300dp”
android:layout_height=”150dp”
android:id=”@+id/logo”
android:layout_centerHorizontal=”true”
android:src=”@mipmap/meicode”/>
<EditText
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:id=”@+id/edtTxtEmail”
android:hint=”Email”
android:layout_below=”@id/logo”
android:layout_marginLeft=”20dp”
android:layout_marginRight=”20dp”
android:inputType=”textEmailAddress”
android:layout_marginTop=”20dp”/>
<EditText
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:id=”@+id/edtTxtPassword”
android:hint=”Password”
android:inputType=”textPassword”
android:layout_below=”@id/edtTxtEmail”
android:layout_marginLeft=”20dp”
android:layout_marginRight=”20dp”
android:layout_marginTop=”20dp”/>
<Button
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:id=”@+id/btnLogin”
android:text=”Login”
android:layout_below=”@+id/edtTxtPassword”
android:layout_marginTop=”20dp”
android:layout_centerHorizontal=”true”
android:background=”@color/orange”/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerHorizontal=”true”
android:id=”@+id/txtWarning”
android:textColor=”@color/colorAccent”
android:text=”warning”
android:layout_below=”@+id/btnLogin”
android:layout_marginTop=”20dp”
android:visibility=”gone”/>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Don’t have an account? register from here”
android:textColor=”@color/blue”
android:layout_below=”@+id/txtWarning”
android:layout_marginTop=”20dp”
android:id=”@+id/txtRegister”
android:layout_centerHorizontal=”true”/>
</RelativeLayout>
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Developed by Meisam at meiCode.org”
android:layout_centerHorizontal=”true”
android:layout_alignParentBottom=”true”
android:layout_marginBottom=”10dp”
android:id=”@+id/txtLicense”
android:textStyle=”italic”/>
</RelativeLayout>
dialog_add_transaction
<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:orientation=”vertical”
android:padding=”20dp”>
<RelativeLayout
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerHorizontal=”true”>
<RelativeLayout
android:id=”@+id/shoppingRelLayout”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”>
<ImageView
android:id=”@+id/shoppingImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:src=”@drawable/ic_cart” />
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerVertical=”true”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/shoppingImage”
android:text=”Shopping”
android:textSize=”20dp”
android:textStyle=”bold” />
</RelativeLayout>
<RelativeLayout
android:id=”@+id/investmentRelLayout”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/shoppingRelLayout”
android:layout_marginTop=”20dp”>
<ImageView
android:id=”@+id/investmentImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:src=”@drawable/ic_investment” />
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerVertical=”true”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/investmentImage”
android:text=”Investment”
android:textSize=”20dp”
android:textStyle=”bold” />
</RelativeLayout>
<RelativeLayout
android:id=”@+id/loanRelLayout”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/investmentRelLayout”
android:layout_marginTop=”20dp”>
<ImageView
android:id=”@+id/loanImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:src=”@drawable/ic_loan” />
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerVertical=”true”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/loanImage”
android:text=”Loan”
android:textSize=”20dp”
android:textStyle=”bold” />
</RelativeLayout>
<RelativeLayout
android:id=”@+id/transactionRelLayout”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/loanRelLayout”
android:layout_marginTop=”20dp”>
<ImageView
android:id=”@+id/transactionImage”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:src=”@drawable/ic_send” />
<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerVertical=”true”
android:layout_marginLeft=”10dp”
android:layout_toRightOf=”@+id/transactionImage”
android:text=”Send/Receive”
android:textSize=”20dp”
android:textStyle=”bold” />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
listitem_transaction.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<androidx.cardview.widget.CardView xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:app=”http://schemas.android.com/apk/res-auto”
android:id=”@+id/parent”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_margin=”10dp”
android:elevation=”10dp”
android:orientation=”vertical”
app:cardCornerRadius=”10dp”>
<RelativeLayout
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:layout_margin=”10dp”>
<TextView
android:id=”@+id/txtAmount”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”+ 0.0″
android:textColor=”@color/green”
android:textSize=”25sp”
android:textStyle=”bold” />
<TextView
android:id=”@+id/txtDesc”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@id/txtAmount”
android:layout_centerVertical=”true”
android:layout_marginTop=”10dp”
android:text=”description”
android:textSize=”18sp” />
<TextView
android:id=”@+id/txtDate”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/txtDesc”
android:layout_marginTop=”10dp”
android:text=”date”
android:textSize=”18sp” />
<TextView
android:id=”@+id/txtSender”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentRight=”true”
android:layout_centerVertical=”true”
android:text=”sender”
android:textSize=”18sp”
android:textStyle=”bold” />
<TextView
android:id=”@+id/txtTransaction”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/txtDate”
android:text=”transaction id” />
</RelativeLayout>
</androidx.cardview.widget.CardView>
AndroidManifest.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”org.meicode.meibank”>
<uses-permission android:name=”android.permission.INTERNET”/>
<application
android:allowBackup=”true”
android:icon=”@mipmap/ic_launcher”
android:label=”@string/app_name”
android:roundIcon=”@mipmap/ic_launcher_round”
android:supportsRtl=”true”
android:theme=”@style/AppTheme”>
<activity android:name=”.WebsiteActivity”></activity>
<activity android:name=”.Authentication.LoginActivity” />
<activity android:name=”.Authentication.RegisterActivity” />
<activity android:name=”.MainActivity”
android:theme=”@style/Theme.AppCompat.Light.NoActionBar”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
</application>
</manifest>
build.gradle
apply plugin: ‘com.android.application’
android {
compileSdkVersion 29
buildToolsVersion “29.0.2”
defaultConfig {
applicationId “org.meicode.meibank”
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName “1.0”
testInstrumentationRunner “androidx.test.runner.AndroidJUnitRunner”
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt’), ‘proguard-rules.pro’
}
}
}
dependencies {
implementation fileTree(dir: ‘libs’, include: [‘*.jar’])
//gson library
implementation ‘com.google.code.gson:gson:2.8.5’
implementation ‘com.google.android.material:material:1.0.0’
implementation ‘com.github.PhilJay:MPAndroidChart:v3.1.0’
implementation ‘androidx.appcompat:appcompat:1.1.0’
implementation ‘androidx.constraintlayout:constraintlayout:1.1.3’
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘androidx.test:runner:1.2.0’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.2.0’
}