commit cf9958d74988b63a5e893aeeab2317692b9eafc2 Author: joaomiranda Date: Wed Nov 19 10:19:28 2025 +0000 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..639c779 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2c751a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..4b81dfa --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,57 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.google.gms.google.services) +} + +android { + namespace = "pt.epvc.bookepvc" + compileSdk = 35 + + defaultConfig { + applicationId = "pt.epvc.bookepvc" + minSdk = 24 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + buildFeatures { + viewBinding = true + } +} + +dependencies { + + implementation(libs.appcompat) + implementation(libs.material) + implementation(libs.activity) + implementation(libs.constraintlayout) + implementation(libs.firebase.auth) + implementation(libs.credentials) + implementation(libs.credentials.play.services.auth) + implementation(libs.googleid) + implementation(libs.firebase.database) + implementation(libs.lifecycle.livedata.ktx) + implementation(libs.lifecycle.viewmodel.ktx) + implementation(libs.navigation.fragment) + implementation(libs.navigation.ui) + implementation("com.github.bumptech.glide:glide:4.16.0") + testImplementation(libs.junit) + androidTestImplementation(libs.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..598a496 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,135 @@ +{ + "project_info": { + "project_number": "406964905525", + "firebase_url": "https://appfitness-diogoaraujo-default-rtdb.firebaseio.com", + "project_id": "appfitness-diogoaraujo", + "storage_bucket": "appfitness-diogoaraujo.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:406964905525:android:670c117046fa2d5e92737c", + "android_client_info": { + "package_name": "com.example.appfitness_diogoaraujo" + } + }, + "oauth_client": [ + { + "client_id": "406964905525-kar1bm8u1fkh2s8hvres922ve297hu4m.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCEJZcwUQJgxTtrlwhx6X3RL2lLmEiPSlk" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "406964905525-f8bd83i5nm11pfsci1k4r3csl22hjk63.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:406964905525:android:db9b3a136612a8ad92737c", + "android_client_info": { + "package_name": "com.example.listadetarefas" + } + }, + "oauth_client": [ + { + "client_id": "406964905525-kar1bm8u1fkh2s8hvres922ve297hu4m.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCEJZcwUQJgxTtrlwhx6X3RL2lLmEiPSlk" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "406964905525-f8bd83i5nm11pfsci1k4r3csl22hjk63.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:406964905525:android:87e31bb3e793bc6c92737c", + "android_client_info": { + "package_name": "pt.epvc.bookepvc" + } + }, + "oauth_client": [ + { + "client_id": "406964905525-kar1bm8u1fkh2s8hvres922ve297hu4m.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCEJZcwUQJgxTtrlwhx6X3RL2lLmEiPSlk" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "406964905525-f8bd83i5nm11pfsci1k4r3csl22hjk63.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:406964905525:android:4baef372e5a1654a92737c", + "android_client_info": { + "package_name": "pt.epvc.myapplication" + } + }, + "oauth_client": [ + { + "client_id": "406964905525-crntsltikktupvnf83ol5q7jqqsnt5tb.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "pt.epvc.myapplication", + "certificate_hash": "d927ad3015ea959e422752128cc5811be6f16444" + } + }, + { + "client_id": "406964905525-kar1bm8u1fkh2s8hvres922ve297hu4m.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCEJZcwUQJgxTtrlwhx6X3RL2lLmEiPSlk" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "406964905525-f8bd83i5nm11pfsci1k4r3csl22hjk63.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/pt/epvc/bookepvc/ExampleInstrumentedTest.java b/app/src/androidTest/java/pt/epvc/bookepvc/ExampleInstrumentedTest.java new file mode 100644 index 0000000..c729e23 --- /dev/null +++ b/app/src/androidTest/java/pt/epvc/bookepvc/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package pt.epvc.bookepvc; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("pt.epvc.bookepvc", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..10814da --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/DetalheLivroActivity.java b/app/src/main/java/pt/epvc/bookepvc/DetalheLivroActivity.java new file mode 100644 index 0000000..5a43db7 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/DetalheLivroActivity.java @@ -0,0 +1,64 @@ +package pt.epvc.bookepvc; + +import android.os.Bundle; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.bumptech.glide.Glide; + +import pt.epvc.bookepvc.models.Livro; + +public class DetalheLivroActivity extends AppCompatActivity { + + private TextView tituloTextView; + private TextView autorTextView; + private ImageView capaImageView; + private TextView resumoTextView; + private TextView editorTextView; + private TextView anoPublicacaoTextView; + private TextView categoriaTextView; + private TextView paginasTextView; + private TextView isbnTextView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_detalhe_livro); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + Livro livro = (Livro) getIntent().getExtras().get("livro"); + tituloTextView = findViewById(R.id.tituloTextView); + autorTextView = findViewById(R.id.autorTextView); + capaImageView = findViewById(R.id.capaImageView); + resumoTextView = findViewById(R.id.resumoTextView); + editorTextView = findViewById(R.id.editorTextView); + anoPublicacaoTextView = findViewById(R.id.anoPublicacaoTextView); + categoriaTextView = findViewById(R.id.categoriaTextView); + paginasTextView = findViewById(R.id.paginasTextView); + isbnTextView = findViewById(R.id.isbnTextView); + if (livro != null) { + tituloTextView.setText(livro.getTitulo()); + autorTextView.setText(livro.getAutor()); + resumoTextView.setText(livro.getResumo()); + editorTextView.setText(livro.getEditor()); + anoPublicacaoTextView.setText(livro.getAnoPublicacao()); + categoriaTextView.setText(livro.getCategoria()); + paginasTextView.setText(livro.getNumeroPaginas()); + Glide.with(this).load(livro.getImagem()).into(capaImageView); + } + + + + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/MainActivity.java b/app/src/main/java/pt/epvc/bookepvc/MainActivity.java new file mode 100644 index 0000000..3e53759 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/MainActivity.java @@ -0,0 +1,85 @@ +package pt.epvc.bookepvc; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.activity.EdgeToEdge; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +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; + +public class MainActivity extends AppCompatActivity { + + private EditText emailEditText; + private EditText passwordEditText; + private Button loginButton; + private TextView esquecimePasswordTextView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_main); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + emailEditText = findViewById(R.id.emailEditText); + passwordEditText = findViewById(R.id.passwordEditText); + loginButton = findViewById(R.id.loginButton); + esquecimePasswordTextView = findViewById(R.id.esquecimePasswordTextView); + + loginButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String email = emailEditText.getText().toString(); + String password = passwordEditText.getText().toString(); + if(email.isBlank()){ + emailEditText.setError("O campo de email é obrigatório"); + return; + } + if(password.isBlank()){ + passwordEditText.setError("O campo de palavra-passe é obrigatório"); + return; + } + FirebaseAuth.getInstance().signInWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if(task.isSuccessful()){ + Intent intent = new Intent(MainActivity.this, PrincipalActivity.class); + startActivity(intent); + finish(); + } + else{ + passwordEditText.setError("Credenciais Inválidas"); + emailEditText.setError("Credenciais Inválidas"); + } + } + }); + } + }); + } + + @Override + protected void onStart() { + super.onStart(); + if(FirebaseAuth.getInstance().getCurrentUser() != null){ + Intent intent = new Intent(MainActivity.this, PrincipalActivity.class); + startActivity(intent); + finish(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/PrincipalActivity.java b/app/src/main/java/pt/epvc/bookepvc/PrincipalActivity.java new file mode 100644 index 0000000..eedef36 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/PrincipalActivity.java @@ -0,0 +1,39 @@ +package pt.epvc.bookepvc; + +import android.os.Bundle; +import android.view.View; + +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + +import pt.epvc.bookepvc.databinding.ActivityPrincipalBinding; +import pt.epvc.bookepvc.models.Livro; + +public class PrincipalActivity extends AppCompatActivity { + + private ActivityPrincipalBinding binding; + private Livro Livro; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityPrincipalBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + BottomNavigationView navView = findViewById(R.id.nav_view); + // Passing each menu ID as a set of Ids because each + // menu should be considered as top level destinations. + AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( + R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications) + .build(); + NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_principal); + //NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); + NavigationUI.setupWithNavController(binding.navView, navController); + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/adapters/CategoriasAdapter.java b/app/src/main/java/pt/epvc/bookepvc/adapters/CategoriasAdapter.java new file mode 100644 index 0000000..964dcf9 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/adapters/CategoriasAdapter.java @@ -0,0 +1,110 @@ +package pt.epvc.bookepvc.adapters; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; + +import pt.epvc.bookepvc.R; +import pt.epvc.bookepvc.models.Livro; + +public class CategoriasAdapter extends RecyclerView.Adapter { + + private ArrayList listaCategorias; + private Context context; + + /** + * Provide a reference to the type of views that you are using + * (custom ViewHolder) + */ + public static class ViewHolder extends RecyclerView.ViewHolder { + private final TextView categoriaTextView; + private final RecyclerView livrosRecyclerView; + + public ViewHolder(View view) { + super(view); + // Define click listener for the ViewHolder's View + + categoriaTextView = (TextView) view.findViewById(R.id.categoriaTextView); + livrosRecyclerView = (RecyclerView) view.findViewById(R.id.livrosRecyclerView); + } + + public TextView getCategoriaTextView() { + return categoriaTextView; + } + public RecyclerView getLivrosRecyclerView() { + return livrosRecyclerView; + } + } + + /** + * Initialize the dataset of the Adapter + * + * @param dataSet String[] containing the data to populate views to be used + * by RecyclerView + */ + public CategoriasAdapter(ArrayList dataSet, Context context) { + listaCategorias = dataSet; + this.context = context; + } + + // Create new views (invoked by the layout manager) + @Override + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + // Create a new view, which defines the UI of the list item + View view = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_principal, viewGroup, false); + + return new ViewHolder(view); + } + + // Replace the contents of a view (invoked by the layout manager) + @Override + public void onBindViewHolder(ViewHolder viewHolder, final int position) { + + // Get element from your dataset at this position and replace the + // contents of the view with that element + viewHolder.getCategoriaTextView().setText(listaCategorias.get(position)); + + + DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference(); + databaseReference.child("livros").addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + ArrayList listaLivros = new ArrayList<>(); + for (DataSnapshot dataSnapshot : snapshot.getChildren()) { + Livro livro = dataSnapshot.getValue(Livro.class); + if (livro.getCategoria().equals(listaCategorias.get(position))){ + listaLivros.add(livro); + } + } + viewHolder.getLivrosRecyclerView().setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)); + viewHolder.getLivrosRecyclerView().setAdapter(new LivrosAdapter(listaLivros,context)); + } + + @Override + public void onCancelled(@NonNull DatabaseError error) { + + } + }); + } + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return listaCategorias.size(); + } +} diff --git a/app/src/main/java/pt/epvc/bookepvc/adapters/LivrosAdapter.java b/app/src/main/java/pt/epvc/bookepvc/adapters/LivrosAdapter.java new file mode 100644 index 0000000..5097fab --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/adapters/LivrosAdapter.java @@ -0,0 +1,98 @@ +package pt.epvc.bookepvc.adapters; + +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; + +import java.util.ArrayList; + +import pt.epvc.bookepvc.DetalheLivroActivity; +import pt.epvc.bookepvc.R; +import pt.epvc.bookepvc.models.Livro; + +public class LivrosAdapter extends RecyclerView.Adapter { + + private Context context; + private ArrayList listaLivros; + + /** + * Provide a reference to the type of views that you are using + * (custom ViewHolder) + */ + public static class ViewHolder extends RecyclerView.ViewHolder { + private final TextView tituloTextView; + private final ImageView livroImageView; + + public ViewHolder(View view) { + super(view); + // Define click listener for the ViewHolder's View + + tituloTextView = (TextView) view.findViewById(R.id.tituloTextView); + livroImageView = (ImageView) view.findViewById(R.id.livroImageView); + } + + public TextView getTituloTextView() { + return tituloTextView; + } + + public ImageView getLivroImageView() { + return livroImageView; + } + } + + /** + * Initialize the dataset of the Adapter + * + * @param listaLivros String[] containing the data to populate views to be used + * by RecyclerView + */ + public LivrosAdapter(ArrayList listaLivros, Context context) { + this.listaLivros = listaLivros; + this.context = context; + } + + // Create new views (invoked by the layout manager) + @Override + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + // Create a new view, which defines the UI of the list item + View view = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_livro, viewGroup, false); + + return new ViewHolder(view); + } + + // Replace the contents of a view (invoked by the layout manager) + @Override + public void onBindViewHolder(ViewHolder viewHolder, final int position) { + + // Get element from your dataset at this position and replace the + // contents of the view with that element + viewHolder.getTituloTextView().setText(listaLivros.get(position).getTitulo()); + Glide.with(context) + .load(listaLivros.get(position).getImagem()) + .into(viewHolder.getLivroImageView()); + viewHolder.getLivroImageView().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(context, DetalheLivroActivity.class); + Livro livro = listaLivros.get(position); + intent.putExtra("livro", livro); + context.startActivity(intent); + } + }); + } + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return listaLivros.size(); + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/models/Livro.java b/app/src/main/java/pt/epvc/bookepvc/models/Livro.java new file mode 100644 index 0000000..f78c0f2 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/models/Livro.java @@ -0,0 +1,112 @@ +package pt.epvc.bookepvc.models; + +import java.io.Serializable; + +public class Livro implements Serializable { + private String titulo; + private String autor; + private String editor; + private String anoPublicacao; + private String categoria; + private String isbn; + private String resumo; + private String id; + private String imagem; + private String numeroPaginas; + + public Livro() { + } + + public Livro(String titulo, String autor, String editor, String anoPublicacao, String categoria, String isbn, String resumo, String id, String imagem, String numeroPaginas) { + this.titulo = titulo; + this.autor = autor; + this.editor = editor; + this.anoPublicacao = anoPublicacao; + this.categoria = categoria; + this.isbn = isbn; + this.resumo = resumo; + this.id = id; + this.imagem = imagem; + this.numeroPaginas = numeroPaginas; + } + + public String getTitulo() { + return titulo; + } + + public void setTitulo(String titulo) { + this.titulo = titulo; + } + + public String getAutor() { + return autor; + } + + public void setAutor(String autor) { + this.autor = autor; + } + + public String getEditor() { + return editor; + } + + public void setEditor(String editor) { + this.editor = editor; + } + + public String getAnoPublicacao() { + return anoPublicacao; + } + + public void setAnoPublicacao(String anoPublicacao) { + this.anoPublicacao = anoPublicacao; + } + + public String getCategoria() { + return categoria; + } + + public void setCategoria(String categoria) { + this.categoria = categoria; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public String getResumo() { + return resumo; + } + + public void setResumo(String resumo) { + this.resumo = resumo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImagem() { + return imagem; + } + + public void setImagem(String imagem) { + this.imagem = imagem; + } + + public String getNumeroPaginas() { + return numeroPaginas; + } + + public void setNumeroPaginas(String numeroPaginas) { + this.numeroPaginas = numeroPaginas; + } +} diff --git a/app/src/main/java/pt/epvc/bookepvc/ui/dashboard/DashboardFragment.java b/app/src/main/java/pt/epvc/bookepvc/ui/dashboard/DashboardFragment.java new file mode 100644 index 0000000..5068be2 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/ui/dashboard/DashboardFragment.java @@ -0,0 +1,37 @@ +package pt.epvc.bookepvc.ui.dashboard; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; + +import pt.epvc.bookepvc.databinding.FragmentDashboardBinding; + +public class DashboardFragment extends Fragment { + + private FragmentDashboardBinding binding; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + DashboardViewModel dashboardViewModel = + new ViewModelProvider(this).get(DashboardViewModel.class); + + binding = FragmentDashboardBinding.inflate(inflater, container, false); + View root = binding.getRoot(); + + final TextView textView = binding.textDashboard; + dashboardViewModel.getText().observe(getViewLifecycleOwner(), textView::setText); + return root; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/ui/dashboard/DashboardViewModel.java b/app/src/main/java/pt/epvc/bookepvc/ui/dashboard/DashboardViewModel.java new file mode 100644 index 0000000..c515f03 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/ui/dashboard/DashboardViewModel.java @@ -0,0 +1,19 @@ +package pt.epvc.bookepvc.ui.dashboard; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class DashboardViewModel extends ViewModel { + + private final MutableLiveData mText; + + public DashboardViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is dashboard fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/ui/home/HomeFragment.java b/app/src/main/java/pt/epvc/bookepvc/ui/home/HomeFragment.java new file mode 100644 index 0000000..bdd7db8 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/ui/home/HomeFragment.java @@ -0,0 +1,67 @@ +package pt.epvc.bookepvc.ui.home; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; + +import pt.epvc.bookepvc.R; +import pt.epvc.bookepvc.adapters.CategoriasAdapter; +import pt.epvc.bookepvc.databinding.FragmentHomeBinding; + +public class HomeFragment extends Fragment { + + private FragmentHomeBinding binding; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + + + binding = FragmentHomeBinding.inflate(inflater, container, false); + View root = binding.getRoot(); + + RecyclerView principalRecyclerView = root.findViewById(R.id.principalRecyclerView); + DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference(); + databaseReference.child("categorias").addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + ArrayList listaCategorias = new ArrayList<>(); + for (DataSnapshot dataSnapshot : snapshot.getChildren()) { + String categoria = dataSnapshot.getValue(String.class); + listaCategorias.add(categoria); + } + CategoriasAdapter adapter = new CategoriasAdapter(listaCategorias, getContext()); + principalRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + principalRecyclerView.setAdapter(adapter); + } + + @Override + public void onCancelled(@NonNull DatabaseError error) { + + } + }); + + return root; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/ui/notifications/NotificationsFragment.java b/app/src/main/java/pt/epvc/bookepvc/ui/notifications/NotificationsFragment.java new file mode 100644 index 0000000..f886772 --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/ui/notifications/NotificationsFragment.java @@ -0,0 +1,37 @@ +package pt.epvc.bookepvc.ui.notifications; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; + +import pt.epvc.bookepvc.databinding.FragmentNotificationsBinding; + +public class NotificationsFragment extends Fragment { + + private FragmentNotificationsBinding binding; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + NotificationsViewModel notificationsViewModel = + new ViewModelProvider(this).get(NotificationsViewModel.class); + + binding = FragmentNotificationsBinding.inflate(inflater, container, false); + View root = binding.getRoot(); + + final TextView textView = binding.textNotifications; + notificationsViewModel.getText().observe(getViewLifecycleOwner(), textView::setText); + return root; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/pt/epvc/bookepvc/ui/notifications/NotificationsViewModel.java b/app/src/main/java/pt/epvc/bookepvc/ui/notifications/NotificationsViewModel.java new file mode 100644 index 0000000..5db15cf --- /dev/null +++ b/app/src/main/java/pt/epvc/bookepvc/ui/notifications/NotificationsViewModel.java @@ -0,0 +1,19 @@ +package pt.epvc.bookepvc.ui.notifications; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class NotificationsViewModel extends ViewModel { + + private final MutableLiveData mText; + + public NotificationsViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is notifications fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_dashboard_black_24dp.xml b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml new file mode 100644 index 0000000..46fc8de --- /dev/null +++ b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000..f8bb0b5 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/app/src/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000..78b75c3 --- /dev/null +++ b/app/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_detalhe_livro.xml b/app/src/main/res/layout/activity_detalhe_livro.xml new file mode 100644 index 0000000..6e1e7bb --- /dev/null +++ b/app/src/main/res/layout/activity_detalhe_livro.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +