Professional Documents
Culture Documents
Notebook Tiya - Expenses
Notebook Tiya - Expenses
Tia Hijaze
Expenses App
*Expenses*
City: Tamra
ID number :
Expenses
So what did I do ?
After I learned the basics with our teachers , I still felt
that I could learn more about designing and UI as a
whole , as I have a hobby of drawing on paper and on
an ipad so I wanted to design things in a proper way.
● implementation 'com.google.firebase:firebase-firestore:24.4.4'
● implementation 'com.google.firebase:firebase-auth:21.1.0'
1. **Adapters:**
Adapters are essential components in Android that
help connect data sources (like Firebase Firestore or
Firebase Realtime Database) to UI elements such as
RecyclerViews or ListViews. Here's why we use
adapters:
- **Data Binding:** Adapters bind data from Firebase
to individual UI elements in a list or grid.
- **Efficient Rendering:** Adapters handle the
recycling of views in RecyclerViews, improving
performance by reusing existing views instead of
creating new ones.
- **Customization:** Adapters allow customization of
how data is displayed in each item of a list or grid.
2. **Models:**
Models, often referred to as POJOs (Plain Old Java
Objects) or data classes, represent the structure of data
retrieved from Firebase. Here's why models are
important:
- **Data Structure:** Models define the structure of
each item of data, including its fields and types (e.g.,
strings, numbers, dates).
- **Mapping Data:** Models help map Firebase
documents or nodes to Java/Kotlin objects, making it
easier to work with data in the app.
- **Encapsulation:** Models encapsulate data and
provide methods to access and manipulate it, following
object-oriented principles.
SPECIAL CLASSES
Category adapter :
public class CategoryAdapter extends
RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ArrayList<UserCategoryBoundary> categories;
private OnClickCategory onClickCategory;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup
parent, int viewType) {
View view =
LayoutInflater.from(parent.getContext()).inflate(R.layout.category_item,
parent, false);
return new CategoryViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder,
int position) {
CategoryViewHolder categoryViewHolder = (CategoryViewHolder) holder;
UserCategoryBoundary categoryBoundary = getItem(position);
categoryViewHolder.category_TV_name.setText(categoryBoundary.getCategoryEnt
ity().getName());
Glide.with(context)
.load(categoryBoundary.getCategoryEntity().getImageUrl())
.into(categoryViewHolder.category_IMG_image);
categoryViewHolder.category_TV_total.setText(categoryBoundary.getTotalPrice
() + " ₪");
@Override
public int getItemCount() {
return this.categories.size();
}
category_IMG_image =
itemView.findViewById(R.id.category_IMG_image);
category_TV_name = itemView.findViewById(R.id.category_TV_name);
category_PI_progress =
itemView.findViewById(R.id.category_PI_progress);
category_TV_total =
itemView.findViewById(R.id.category_TV_total);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UserCategoryBoundary categoryBoundary =
getItem(getAdapterPosition());
int position = getAdapterPosition();
onClickCategory.onClick(categoryBoundary, position);
}
});
}
}
}
public CategoryEntity(){}
Category item :
Product adapter :
public class ProductAdapter extends
RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Context context;
private List<CategoryItem> categoryItems;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup
parent, int viewType) {
View view =
LayoutInflater.from(parent.getContext()).inflate(R.layout.product_item,
parent, false);
return new ProductAdapter.ProductViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder,
int position) {
ProductAdapter.ProductViewHolder productViewHolder =
(ProductAdapter.ProductViewHolder) holder;
CategoryItem categoryItem = getItem(position);
productViewHolder.product_TV_name.setText(categoryItem.getTitle());
productViewHolder.product_TV_price.setText(categoryItem.getPrice() +
" ₪");
}
}
}
}
package com.example.expensesapp.entity;
import java.io.Serializable;
import java.util.Date;
public CategoryItem() {
this.date = new Date();
}
public String getTitle() {
return title;
}
And they all work together so that they can get all the
details from a specified category to see what products
their money was spent on.
I also have organised the classes in my application very
well
Look at the organising
package com.example.expensesapp.auth;
public AuthUser(){}
public AuthUser(String email, String password){
this.email = email;
this.password = password;
}
public String getEmail() {
return email;
}
Auth controller :
package com.example.expensesapp.controller;
import androidx.annotation.NonNull;
import com.example.expensesapp.auth.AuthUser;
import com.example.expensesapp.callback.AuthCallBack;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public AuthController() {
this.mAuth = FirebaseAuth.getInstance();
}
signup_BTN_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email =
signup_TF_email.getEditText().getText().toString();
String password =
signup_TF_password.getEditText().getText().toString();
if(!checkInput()){
Toast.makeText(SignupActivity.this, "Please check your
inputs!", Toast.LENGTH_SHORT).show();
return;
}
}
});
And we also have the eye icon vector asset , and its
objective is so that we can get to see the password or
unsee it if we want
1- home fragment
2- update fragment
3- profile fragment
getSupportFragmentManager().beginTransaction().add(R.id.home_FL_home,
homeFragment).commit();
getSupportFragmentManager().beginTransaction().add(R.id.home_FL_profile,
profileFragment).commit();
getSupportFragmentManager().beginTransaction().add(R.id.home_FL_update,
updateFragment).commit();
home_FL_profile.setVisibility(View.INVISIBLE);
home_FL_update.setVisibility(View.INVISIBLE);
home_BN.setOnItemSelectedListener(new
NavigationBarView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item)
{
if(item.getItemId() == R.id.home){
// home
home_FL_profile.setVisibility(View.INVISIBLE);
home_FL_update.setVisibility(View.INVISIBLE);
home_FL_home.setVisibility(View.VISIBLE);
}else if (item.getItemId() == R.id.profile){
//profile
home_FL_profile.setVisibility(View.VISIBLE);
home_FL_update.setVisibility(View.INVISIBLE);
home_FL_home.setVisibility(View.INVISIBLE);
}else {
// update
home_FL_profile.setVisibility(View.INVISIBLE);
home_FL_update.setVisibility(View.VISIBLE);
home_FL_home.setVisibility(View.INVISIBLE);
}
return true;
}
});
, and here i will show you the code that will save the
data .
private void addItemToCategory(){
Home fragment
Where we first see the categories of what we have spent
our money upon, and then we see the represented
photo that i have already put in the firebase storage
For the specified category option . and then on the right
we see a number and that adds up all of the money that
was spent on that specific category
And if you click on it it will retrieve the data of all the
saved expenses from that specified category and show
them
From getting help from recyclerview and the product
item in the xml
And here is how it would look for all the expenses spent
on a specified category
And as you basically see the price at the top shows all
the sum of the expenses , and at the top we see the
category option
The limit for the category spendings are 1000 , and once
you exceed the thousand you will see the progress bar
being over populated and filled up to the brink.
And then it will update your profile picture and once you
log in once again to the profile fragment you will see
your profile picture updated and present
Home activity
editProfile dashboard
{ android
'namespace 'com.example.expensesapp
compileSdk 33
{ defaultConfig
"applicationId "com.example.expensesapp
minSdk 24
targetSdk 33
versionCode 1
"versionName "1.0
"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner
}
{ buildTypes
{ release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-
'optimize.txt'), 'proguard-rules.pro
}
}
{ compileOptions
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
{ dependencies
implementation platform('com.google.firebase:firebase-bom:32.6.0')
'implementation 'com.github.bumptech.glide:glide:4.16.0
"implementation "com.google.firebase:firebase-auth
"implementation "com.google.firebase:firebase-database
"implementation "com.google.firebase:firebase-storage
'implementation 'de.hdodenhof:circleimageview:3.1.0
'implementation 'androidx.appcompat:appcompat:1.6.1
'implementation 'com.google.android.material:material:1.8.0
'implementation 'androidx.constraintlayout:constraintlayout:2.1.4
'testImplementation 'junit:junit:4.13.2
'androidTestImplementation 'androidx.test.ext:junit:1.1.5
'androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher_icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_icon_round"
android:supportsRtl="false"
android:theme="@style/Theme.ExpensesApp"
tools:targetApi="31">
<activity
android:name=".main.CompareCategoryActivity"
android:exported="false" />
<activity
android:name=".main.DashboardActivity"
android:exported="false" />
<activity
android:name=".main.UpdateProfileActivity"
android:exported="false" />
<activity
android:name=".main.CategoryActivity"
android:exported="false" />
<activity
android:name=".main.HomeActivity"
android:exported="false" />
<activity
android:name=".auth.SignupActivity"
android:exported="false" />
<activity
android:name=".auth.LoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Future opportunities :
I feel that this is just the beginning for the app , as at the
moment it is an organiser for what you spend your
money on , and i want that in the future i add an option
to add credit card information just like apple pay , so that
you can pay with the app , and that if you cross the limit
of what you allowed for yourself , you can’t then spend
that money , i feel like younger people who might feel
unorganised when managing money will benefit the
most from this app , and i am really excited to represent
this project.
Reflection:
Reflection :
Completing the managing Expenses app project was an
incredible achievement for me. It was a project that challenged
me in many ways, and required a lot of hard work, dedication,
and persistence.