MVVM tests

This commit is contained in:
valentin 2020-12-24 16:37:34 +01:00
parent 7dc95277c2
commit b35f86cd0d
17 changed files with 280 additions and 37 deletions

View File

@ -34,6 +34,8 @@ dependencies {
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.room:room-runtime:2.2.5" implementation "androidx.room:room-runtime:2.2.5"
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
annotationProcessor "androidx.room:room-compiler:2.2.5" annotationProcessor "androidx.room:room-compiler:2.2.5"
testImplementation 'junit:junit:4.+' testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2'

View File

@ -0,0 +1,24 @@
<resources>
<!--
TODO: Before you run your application, you need a Google Maps API key.
To get one, follow this link, follow the directions and press "Create" at the end:
https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=01:3E:04:87:2F:D1:3F:E0:D7:2C:3F:F2:82:19:D4:FA:28:64:84:4D%3Bfr.romanet.vj.apps.myrealestateagency.view
You can also add your credentials to an existing key, using these values:
Package name:
fr.romanet.vj.apps.myrealestateagency.view
SHA-1 certificate fingerprint:
01:3E:04:87:2F:D1:3F:E0:D7:2C:3F:F2:82:19:D4:FA:28:64:84:4D
Alternatively, follow the directions here:
https://developers.google.com/maps/documentation/android/start#get-key
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyAAltvI3LZ9wAOuygKQybgJN5tIQhPk_Hg</string>
</resources>

View File

@ -2,6 +2,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.romanet.vj.apps.myrealestateagency"> package="fr.romanet.vj.apps.myrealestateagency">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the "MyLocation" functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -9,7 +17,23 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MyRealEstateAgency"> android:theme="@style/Theme.MyRealEstateAgency">
<activity android:name=".MainActivity">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".view.MapsActivity"
android:label="@string/title_activity_maps"></activity>
<activity android:name=".view.MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@ -6,11 +6,11 @@ import androidx.room.Transaction;
import java.util.List; import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.entities.AgencyWithProperties; //import fr.romanet.vj.apps.myrealestateagency.entities.AgencyWithProperties;
@Dao //@Dao
public interface AgencyWithPropertiesDao { //public interface AgencyWithPropertiesDao {
@Transaction // @Transaction
@Query("SELECT * FROM agency") // @Query("SELECT * FROM agency")
List<AgencyWithProperties> getAgenciesAndProperties(); // List<AgencyWithProperties> getAgenciesAndProperties();
} //}

View File

@ -9,7 +9,7 @@ import androidx.room.TypeConverters;
import fr.romanet.vj.apps.myrealestateagency.dao.AgencyDao; import fr.romanet.vj.apps.myrealestateagency.dao.AgencyDao;
import fr.romanet.vj.apps.myrealestateagency.dao.AgencyWithAgentsDao; import fr.romanet.vj.apps.myrealestateagency.dao.AgencyWithAgentsDao;
import fr.romanet.vj.apps.myrealestateagency.dao.AgencyWithPropertiesDao; //import fr.romanet.vj.apps.myrealestateagency.dao.AgencyWithPropertiesDao;
import fr.romanet.vj.apps.myrealestateagency.dao.PropertyDao; import fr.romanet.vj.apps.myrealestateagency.dao.PropertyDao;
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.Agent;
@ -24,6 +24,6 @@ public abstract class RealEstateAgencyDatabase extends RoomDatabase {
public abstract AgencyDao agencyDao(); public abstract AgencyDao agencyDao();
public abstract PropertyDao propertyDao(); public abstract PropertyDao propertyDao();
public abstract AgencyWithAgentsDao agencyWithAgentsDao(); public abstract AgencyWithAgentsDao agencyWithAgentsDao();
public abstract AgencyWithPropertiesDao agencyWithPropertiesDaoDao(); // public abstract AgencyWithPropertiesDao agencyWithPropertiesDaoDao();
} }

View File

@ -5,11 +5,11 @@ import androidx.room.Relation;
import java.util.List; import java.util.List;
public class AgencyWithProperties { //public class AgencyWithProperties {
public int agency_id; // public int agency_id;
@Relation( // @Relation(
parentColumn = "agency_id", // parentColumn = "agency_id",
entityColumn = "belongs_agency_id" // entityColumn = "belongs_agency_id"
) // )
public List<AgencyWithProperties> agents; // public List<AgencyWithProperties> agents;
} //}

View File

@ -0,0 +1,7 @@
package fr.romanet.vj.apps.myrealestateagency.repository;
import androidx.lifecycle.LifecycleObserver;
public class MainActivityRepository implements LifecycleObserver {
}

View File

@ -0,0 +1,15 @@
package fr.romanet.vj.apps.myrealestateagency.repository;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import java.io.IOException;
import java.util.List;
public class MapsActivityRepository {
public List<Address> get_lat_long_from_address(String address, Context context) throws IOException {
Geocoder gc = new Geocoder(context);
return gc.getFromLocationName(address, 1);
}
}

View File

@ -1,9 +1,14 @@
package fr.romanet.vj.apps.myrealestateagency.Repository; package fr.romanet.vj.apps.myrealestateagency.repository;
import android.content.Context; import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import androidx.room.Room; import androidx.room.Room;
import java.io.IOException;
import java.util.List;
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.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent; import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
@ -36,4 +41,7 @@ public final class MyRealEstateAgencyRepository {
public void addAgency(Agency agency){realEstateAgencyDatabaseDatabase.agencyDao().insertAgency(agency);} public void addAgency(Agency agency){realEstateAgencyDatabaseDatabase.agencyDao().insertAgency(agency);}
public void addAgent(Agent agent){realEstateAgencyDatabaseDatabase.agentDao().insertAgent(agent);} public void addAgent(Agent agent){realEstateAgencyDatabaseDatabase.agentDao().insertAgent(agent);}
} }

View File

@ -1,28 +1,43 @@
package fr.romanet.vj.apps.myrealestateagency; package fr.romanet.vj.apps.myrealestateagency.view;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.util.Log; import androidx.lifecycle.ViewModelProvider;
import android.content.Intent;
import android.view.View; import android.view.View;
import java.util.ArrayList;
import java.util.List;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.widget.TextView;
import fr.romanet.vj.apps.myrealestateagency.Repository.MyRealEstateAgencyRepository; import fr.romanet.vj.apps.myrealestateagency.R;
import fr.romanet.vj.apps.myrealestateagency.database.RealEstateAgencyDatabase; import fr.romanet.vj.apps.myrealestateagency.repository.MyRealEstateAgencyRepository;
import fr.romanet.vj.apps.myrealestateagency.entities.Agency; import fr.romanet.vj.apps.myrealestateagency.entities.Agency;
import fr.romanet.vj.apps.myrealestateagency.entities.AgencyWithAgents;
import fr.romanet.vj.apps.myrealestateagency.entities.Agent; import fr.romanet.vj.apps.myrealestateagency.entities.Agent;
import fr.romanet.vj.apps.myrealestateagency.viewmodel.MainActivityViewModel;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static final String TAG = "MyActivity"; private static final String TAG = "MyActivity";
// - Init ViewModel
MainActivityViewModel mainActivityViewModel;
// - Init widgets
private TextView tv1;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
// - Define widget
tv1 = (TextView) findViewById(R.id.tv1);
// - Link the ViewModel
mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
getLifecycle().addObserver(mainActivityViewModel);
observe_counter();
} }
public void insertSingleTodo(View view) { public void insertSingleTodo(View view) {
@ -45,4 +60,17 @@ public class MainActivity extends AppCompatActivity {
String query = "SELECT agency_id FROM agency INNER JOIN agent ON agency.agency_id = agent.agent_id WHERE agency_name =" + "AgenceOFParis" + "GROUP BY agency_name"; String query = "SELECT agency_id FROM agency INNER JOIN agent ON agency.agency_id = agent.agent_id WHERE agency_name =" + "AgenceOFParis" + "GROUP BY agency_name";
String query1 = "SELECT agency_id FROM agent INNER JOIN agency ON agency.agency_id = agent.agent_id WHERE agency_name =" + "AgenceOFParis" + "GROUP BY agency_name"; String query1 = "SELECT agency_id FROM agent INNER JOIN agency ON agency.agency_id = agent.agent_id WHERE agency_name =" + "AgenceOFParis" + "GROUP BY agency_name";
} }
public void BTN_go_to_map(View view){
Intent i = new Intent(MainActivity.this, MapsActivity.class);
MainActivity.this.startActivity(i);
}
public void observe_counter(){
mainActivityViewModel.counter.observe(this, counter ->
{
tv1.setText(counter.toString());
});
}
} }

View File

@ -0,0 +1,53 @@
package fr.romanet.vj.apps.myrealestateagency.view;
import androidx.fragment.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.List;
import fr.romanet.vj.apps.myrealestateagency.R;
import fr.romanet.vj.apps.myrealestateagency.repository.MapsActivityRepository;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
// mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
// List<String> ll = MapsActivityRepository.get
}
}

View File

@ -0,0 +1,40 @@
package fr.romanet.vj.apps.myrealestateagency.viewmodel;
import android.os.Handler;
import android.os.SystemClock;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ViewModel;
import fr.romanet.vj.apps.myrealestateagency.view.MainActivity;
public final class MainActivityViewModel extends ViewModel implements LifecycleObserver {
public enum LoadingState
{
Loading, Loaded
}
public MutableLiveData<LoadingState> loadingState = new MutableLiveData<>();
public MutableLiveData<Integer> counter = new MutableLiveData<>();
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void start_counter_on_activity_start(){
counter.postValue(0);
for (int i = 0; i<10; i++){
new Handler().postDelayed(() ->
{
counter.postValue(15);
}, i*1000);
// counter.postValue(i);
// SystemClock.sleep(1000);
}
}
}

View File

@ -4,28 +4,40 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".view.MainActivity">
<TextView <TextView
android:id="@+id/textView" android:id="@+id/tv1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!" android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
<Button <Button
android:id="@+id/buttonZ" android:id="@+id/buttonZ"
android:layout_width="95dp" android:layout_width="95dp"
android:layout_height="56dp" android:layout_height="56dp"
android:layout_marginBottom="204dp"
android:onClick="insertSingleTodo" android:onClick="insertSingleTodo"
android:text="Button" android:text="Button"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toEndOf="@+id/textView" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0.526" app:layout_constraintTop_toBottomOf="@+id/tv1" />
app:layout_constraintStart_toStartOf="@+id/textView" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:onClick="BTN_go_to_map"
android:text="To Map ->"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonZ" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.MapsActivity" />

View File

@ -1,3 +1,4 @@
<resources> <resources>
<string name="app_name">My Real Estate Agency</string> <string name="app_name">My Real Estate Agency</string>
<string name="title_activity_maps">Map</string>
</resources> </resources>

View File

@ -0,0 +1,20 @@
<resources>
<!--
TODO: Before you release your application, you need a Google Maps API key.
To do this, you can either add your release key credentials to your existing
key, or create a new key.
Note that this file specifies the API key for the release build target.
If you have previously set up a key for the debug target with the debug signing certificate,
you will also need to set up a key for your release certificate.
Follow the directions here:
https://developers.google.com/maps/documentation/android/signup
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>

View File

@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:4.1.0" classpath 'com.android.tools.build:gradle:4.1.1'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files