Adding the list of properties in the second screen

This commit is contained in:
BGbaderguet 2020-12-30 19:20:37 +01:00
parent 53a2c9f9d0
commit a7dc63d6c9
22 changed files with 357 additions and 16 deletions

View File

@ -19,6 +19,11 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MyRealEstateAgency"> android:theme="@style/Theme.MyRealEstateAgency">
<activity
android:name=".view.PropertiesActivity"
android:parentActivityName=".view.AgentsActivity"
android:theme="@style/Theme.MyRealEstateAgency"></activity>
<activity android:name=".view.AgentsActivity"> <activity android:name=".view.AgentsActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@ -2,6 +2,7 @@ package fr.romanet.vj.apps.myrealestateagency.adapter;
import java.util.List; import java.util.List;
import android.content.Intent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -13,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import fr.romanet.vj.apps.myrealestateagency.adapter.AgentsAdapter.AgentViewHolder; import fr.romanet.vj.apps.myrealestateagency.adapter.AgentsAdapter.AgentViewHolder;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent; import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
import fr.romanet.vj.apps.myrealestateagency.R; import fr.romanet.vj.apps.myrealestateagency.R;
import fr.romanet.vj.apps.myrealestateagency.view.PropertiesActivity;
public final class AgentsAdapter extends Adapter<AgentViewHolder>{ public final class AgentsAdapter extends Adapter<AgentViewHolder>{
@ -36,7 +38,18 @@ public final class AgentsAdapter extends Adapter<AgentViewHolder>{
{ {
agentFirstName.setText("First name : " + agent.agentFirstName); agentFirstName.setText("First name : " + agent.agentFirstName);
agentLastName.setText("Last name : " + agent.agentLastName); agentLastName.setText("Last name : " + agent.agentLastName);
agencyName.setText("Agency : " + agent.nameOfAgency); agencyName.setText("Agency : " + agent.getAgency().agencyName);
itemView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
final Intent intent = new Intent(itemView.getContext(), PropertiesActivity.class);
intent.putExtra(PropertiesActivity.AGENCY_EXTRA, agent.getAgency());
itemView.getContext().startActivity(intent);
}
});
} }
} }

View File

@ -0,0 +1,68 @@
package fr.romanet.vj.apps.myrealestateagency.adapter;
import java.util.List;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView.Adapter;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import fr.romanet.vj.apps.myrealestateagency.adapter.PropertiesAdapter.PropertiesViewHolder;
import fr.romanet.vj.apps.myrealestateagency.R;
import fr.romanet.vj.apps.myrealestateagency.entities.Property;
public class PropertiesAdapter extends Adapter<PropertiesViewHolder> {
public static final class PropertiesViewHolder extends ViewHolder {
private final TextView agencyAddress;
private final TextView agencyDescription;
private final TextView agencyPrice;
public PropertiesViewHolder(@NonNull View itemView)
{
super(itemView);
agencyAddress = itemView.findViewById(R.id.propertyAddress);
agencyDescription = itemView.findViewById(R.id.propertyDescription);
agencyPrice = itemView.findViewById(R.id.propertyPrice);
}
public void update(final Property property)
{
agencyAddress.setText("Address : " + property.address);
agencyDescription.setText("Description : " + property.description);
agencyPrice.setText("Price : ");
}
}
private final List<Property> properties;
public PropertiesAdapter(List<Property> properties)
{
this.properties = properties;
}
@NonNull
@Override
public PropertiesAdapter.PropertiesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewholder_properties, parent, false);
return new PropertiesAdapter.PropertiesViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull PropertiesAdapter.PropertiesViewHolder holder, int position)
{
holder.update(properties.get(position));
}
@Override
public int getItemCount()
{
return properties.size();
}
}

View File

@ -1,5 +1,6 @@
package fr.romanet.vj.apps.myrealestateagency.dao; package fr.romanet.vj.apps.myrealestateagency.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
@ -7,16 +8,22 @@ import androidx.room.Query;
import java.util.List; import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency; import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
import fr.romanet.vj.apps.myrealestateagency.entities.Property;
@Dao @Dao
public interface AgencyDao { public interface AgencyDao {
@Query("SELECT * FROM agency") @Query("SELECT * FROM agency")
List<Agency> getAgencyList(); LiveData<List<Agency>> getAgencyList();
@Insert @Insert
void insertAgency(Agency agency); void insertAgency(Agency agency);
@Insert @Insert
void insertPreData(Agency[] agencies); void insertPreData(Agency[] agencies);
@Query("SELECT property_id, description, address, longitude, latitude, belongs_agency_id, statue_sale, sold_date, price, type_description, number_rooms, surface_area " +
"FROM property INNER JOIN agency ON agency.agency_id = property.belongs_agency_id WHERE agency.agency_id = :idAgency")
LiveData<List<Property>> getPropertiesList(int idAgency);
} }

View File

@ -4,9 +4,11 @@ import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.RoomWarnings;
import java.util.List; import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent; import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
@Dao @Dao
@ -15,8 +17,8 @@ public interface AgentDao {
@Query("SELECT * FROM agent") @Query("SELECT * FROM agent")
LiveData<List<Agent>> getAgentList(); LiveData<List<Agent>> getAgentList();
@Query("SELECT agency_name FROM agency INNER JOIN agent ON agent.agency_employer_id = agency.agency_id WHERE agent.agent_id = :idAgent") @Query("SELECT agency_id, agency_name FROM agency INNER JOIN agent ON agent.agency_employer_id = agency.agency_id WHERE agent.agent_id = :idAgent")
String getAgencyName(int idAgent); Agency getAgency(int idAgent);
@Insert @Insert
void insertAgent(Agent agent); void insertAgent(Agent agent);

View File

@ -6,6 +6,7 @@ import androidx.room.Query;
import java.util.List; import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
import fr.romanet.vj.apps.myrealestateagency.entities.Property; import fr.romanet.vj.apps.myrealestateagency.entities.Property;
@Dao @Dao
@ -15,4 +16,7 @@ public interface PropertyDao {
@Insert @Insert
void insertProperty(Property property); void insertProperty(Property property);
@Insert
void insertPreProperties(Property[] properties);
} }

View File

@ -55,6 +55,7 @@ public abstract class RealEstateAgencyDatabase extends RoomDatabase {
public void run() { public void run() {
getInstance(context).agencyDao().insertPreData(Agency.populateAgencyTable()); getInstance(context).agencyDao().insertPreData(Agency.populateAgencyTable());
getInstance(context).agentDao().insertPreAgents(Agent.populateAgentsTable()); getInstance(context).agentDao().insertPreAgents(Agent.populateAgentsTable());
getInstance(context).propertyDao().insertPreProperties(Property.populatePropertyTable());
} }
}); });
} }

View File

@ -5,11 +5,13 @@ import androidx.room.Entity;
import androidx.room.Index; import androidx.room.Index;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import java.io.Serializable;
//Parent class of agent (indeed, zero or many agents can work in an agency) //Parent class of agent (indeed, zero or many agents can work in an agency)
@Entity(tableName = "agency", @Entity(tableName = "agency",
indices = {@Index("agency_id"), indices = {@Index("agency_id"),
@Index(value = {"agency_name"}, unique = true)}) @Index(value = {"agency_name"}, unique = true)})
public class Agency { public class Agency implements Serializable {
@ColumnInfo(name = "agency_id") @ColumnInfo(name = "agency_id")
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

View File

@ -7,6 +7,8 @@ import androidx.room.Ignore;
import androidx.room.Index; import androidx.room.Index;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import fr.romanet.vj.apps.myrealestateagency.database.RealEstateAgencyDatabase;
import static androidx.room.ForeignKey.CASCADE; import static androidx.room.ForeignKey.CASCADE;
//Child class of Agency (indeed, an agent work only in one agency) //Child class of Agency (indeed, an agent work only in one agency)
@ -32,7 +34,7 @@ public class Agent {
public int agencyEmployerId; public int agencyEmployerId;
@Ignore @Ignore
public String nameOfAgency; public Agency agency;
public Agent(String agentFirstName, String agentLastName, int agencyEmployerId) public Agent(String agentFirstName, String agentLastName, int agencyEmployerId)
{ {
@ -47,9 +49,14 @@ public class Agent {
return agentFirstName; return agentFirstName;
} }
public void setNameOfAgency(String nameOfAgency) public void setAgency(Agency agency)
{ {
this.nameOfAgency = nameOfAgency; this.agency = agency;
}
public Agency getAgency()
{
return this.agency;
} }
public int getAgencyEmployerId() {return agencyEmployerId;} public int getAgencyEmployerId() {return agencyEmployerId;}

View File

@ -67,4 +67,12 @@ public class Property {
return date == null ? null : date.getTime(); return date == null ? null : date.getTime();
} }
} }
public static Property[] populatePropertyTable() {
return new Property[]{
new Property("Amazing property in the best district of Paris", "15 rue Champs-Elysée", 15.8, 17.8, 1),
new Property("Best appartment in Velizy-Villacoublay", "Rue de Villacoublay, 78140 Vélizy-Villacoublay", 19.8, 20.8, 1),
new Property("Amazing property in the best district of Marseille", "15 rue de Marseille", 15.8, 17.8, 1),
};
}
} }

View File

@ -0,0 +1,33 @@
package fr.romanet.vj.apps.myrealestateagency.repository;
import android.app.Application;
import androidx.lifecycle.LiveData;
import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.dao.AgencyDao;
import fr.romanet.vj.apps.myrealestateagency.database.RealEstateAgencyDatabase;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Property;
public class AgencyRepository {
public AgencyDao agencyDao;
public LiveData<List<Agency>> allAgencies;
public AgencyRepository(Application application) {
RealEstateAgencyDatabase realEstateAgencyDatabase = RealEstateAgencyDatabase.getInstance(application);
agencyDao = realEstateAgencyDatabase.agencyDao();
allAgencies = agencyDao.getAgencyList();
}
public LiveData<List<Agency>> getAllAgencies() {
return allAgencies;
}
public LiveData<List<Property>> getProperties(Agency agency)
{
return agencyDao.getPropertiesList(agency.agencyId);
}
}

View File

@ -8,6 +8,7 @@ import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.dao.AgentDao; import fr.romanet.vj.apps.myrealestateagency.dao.AgentDao;
import fr.romanet.vj.apps.myrealestateagency.database.RealEstateAgencyDatabase; import fr.romanet.vj.apps.myrealestateagency.database.RealEstateAgencyDatabase;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent; import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
public class AgentRepository { public class AgentRepository {
@ -25,8 +26,8 @@ public class AgentRepository {
return allAgents; return allAgents;
} }
public String getAgencyName(Agent agent) public Agency getAgency(Agent agent)
{ {
return agentDao.getAgencyName(agent.agentId); return agentDao.getAgency(agent.agentId);
} }
} }

View File

@ -0,0 +1,58 @@
package fr.romanet.vj.apps.myrealestateagency.view;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.R;
import fr.romanet.vj.apps.myrealestateagency.adapter.AgentsAdapter;
import fr.romanet.vj.apps.myrealestateagency.adapter.PropertiesAdapter;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
import fr.romanet.vj.apps.myrealestateagency.entities.Property;
import fr.romanet.vj.apps.myrealestateagency.viewmodel.PropertiesActivityViewModel;
import fr.romanet.vj.apps.myrealestateagency.viewmodel.PropertiesActivityViewModelFactory;
public class PropertiesActivity extends AppCompatActivity {
public static final String AGENCY_EXTRA = "agencyExtra";
private Bundle extras;
private PropertiesActivityViewModel viewModel;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_properties);
recyclerView = findViewById(R.id.recyclerViewProperties);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
Agency agency = (Agency) getIntent().getSerializableExtra("agencyExtra");
viewModel = new ViewModelProvider(this, new PropertiesActivityViewModelFactory(this.getApplication(), agency)).get(PropertiesActivityViewModel.class);
observeProperties();
}
private void observeProperties()
{
viewModel.properties.observe(this, new Observer<List<Property>>()
{
@Override
public void onChanged(List<Property> properties)
{
final PropertiesAdapter propertiesAdapter = new PropertiesAdapter(properties);
recyclerView.setAdapter(propertiesAdapter);
}
});
}
}

View File

@ -9,6 +9,7 @@ import androidx.lifecycle.MutableLiveData;
import java.util.List; import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent; import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
import fr.romanet.vj.apps.myrealestateagency.repository.AgentRepository; import fr.romanet.vj.apps.myrealestateagency.repository.AgentRepository;
@ -30,8 +31,8 @@ public class AgentsActivityViewModel extends AndroidViewModel {
for(int i = 0; i < currentList.size(); i++) for(int i = 0; i < currentList.size(); i++)
{ {
Agent currentAgent = currentList.get(i); Agent currentAgent = currentList.get(i);
String nameOfAgency = agentRepository.getAgencyName(currentList.get(i)); Agency agency = agentRepository.getAgency(currentList.get(i));
currentAgent.setNameOfAgency(nameOfAgency); currentAgent.setAgency(agency);
} }
} }
} }

View File

@ -0,0 +1,32 @@
package fr.romanet.vj.apps.myrealestateagency.viewmodel;
import android.app.Application;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Property;
import fr.romanet.vj.apps.myrealestateagency.repository.AgencyRepository;
import fr.romanet.vj.apps.myrealestateagency.view.PropertiesActivity;
public class PropertiesActivityViewModel extends AndroidViewModel {
public AgencyRepository agencyRepository;
public LiveData<List<Property>> properties = new MutableLiveData<>();
public PropertiesActivityViewModel(Application application, Agency agency)
{
super(application);
agencyRepository = new AgencyRepository(application);
properties = agencyRepository.getProperties(agency);
}
}

View File

@ -0,0 +1,25 @@
package fr.romanet.vj.apps.myrealestateagency.viewmodel;
import android.app.Application;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
public class PropertiesActivityViewModelFactory implements ViewModelProvider.Factory {
private Application mApplication;
private Agency mParam;
public PropertiesActivityViewModelFactory(Application application, Agency param) {
mApplication = application;
mParam = param;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new PropertiesActivityViewModel(mApplication, mParam);
}
}

View File

@ -0,0 +1,7 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M15,17h2v-3h1v-2l-1,-5H2l-1,5v2h1v6h9v-6h4V17zM9,18H4v-4h5V18z"/>
<path android:fillColor="@android:color/white" android:pathData="M2,4h15v2h-15z"/>
<path android:fillColor="@android:color/white" android:pathData="M20,18l0,-3l-2,0l0,3l-3,0l0,2l3,0l0,3l2,0l0,-3l3,0l0,-2z"/>
</vector>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewProperties"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_agency_add"
app:backgroundTint="@color/white"
app:fabSize="normal"
android:layout_margin="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="12dp">
<TextView
android:id="@+id/propertyAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/propertyDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<TextView
android:id="@+id/propertyDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/propertyAddress"
app:layout_constraintTop_toBottomOf="@id/propertyAddress"
tools:text="@tools:sample/full_names"
/>
<TextView
android:id="@+id/propertyPrice"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/propertyDescription"
app:layout_constraintTop_toBottomOf="@id/propertyDescription"
tools:text="@tools:sample/full_names"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -4,11 +4,9 @@
<!-- Primary brand color. --> <!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item> <item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item> <item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. --> <!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item> <item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item> <item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. --> <!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. --> <!-- Customize your theme here. -->

View File

@ -5,6 +5,5 @@
<color name="purple_700">#FF3700B3</color> <color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color> <color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color> <color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
</resources> </resources>

View File

@ -8,7 +8,6 @@
<!-- Secondary brand color. --> <!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item> <item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item> <item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. --> <!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. --> <!-- Customize your theme here. -->