Compare commits

..

9 Commits

10 changed files with 246 additions and 19 deletions

View File

@ -5,6 +5,7 @@
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="PLATFORM" /> <option name="testRunner" value="PLATFORM" />
<option name="disableWrapperSourceDistributionNotification" value="true" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" /> <option name="gradleJvm" value="1.8" />

View File

@ -38,4 +38,6 @@ dependencies {
testImplementation 'junit:junit:4.+' testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"
} }

View File

@ -9,7 +9,8 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MyWeather"> android:theme="@style/Theme.MyWeather">
<!-- Adding an attribute to remove the app bar only in the activity that allows the user to add a city--> <!-- Adding an attribute to remove the app bar (.NoActionBar) only in the activity that allows the user to add a city, also declaring
the mainActivity as a parent of AddCity activity in order to go back to the mainActivity screen-->
<activity android:name=".AddCity" <activity android:name=".AddCity"
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:theme="@style/Theme.MyWeather.NoActionBar"> android:theme="@style/Theme.MyWeather.NoActionBar">
@ -17,7 +18,6 @@
<activity android:name=".MainActivity"> <activity android:name=".MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@ -2,41 +2,55 @@ package fr.romanet.vj.apps.myweather;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import fr.romanet.vj.apps.myweather.bo.City;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import fr.romanet.vj.apps.myweather.repository.CityRepository;
public class AddCity extends AppCompatActivity { public class AddCity extends AppCompatActivity {
private EditText cityName;
@Override @Override
protected void onCreate(Bundle savedInstanceState) protected void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.add_city_page); setContentView(R.layout.add_city_page);
Toolbar toolbarAddCity = (Toolbar) findViewById(R.id.toolbarAddCity); Toolbar toolbarAddCity = (Toolbar) findViewById(R.id.toolbarAddCity);
setSupportActionBar(toolbarAddCity); setSupportActionBar(toolbarAddCity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true);
Button button = (Button) findViewById(R.id.btnSaveCity); Button button = (Button) findViewById(R.id.btnSaveCity);
button.setOnClickListener(new View.OnClickListener() { button.setOnClickListener(new View.OnClickListener()
public void onClick(View v) { {
EditText editTextnewCity = (EditText) findViewById(R.id.editTextNewCity); public void onClick(View v)
String newCity = (String) editTextnewCity.getText().toString(); {
if(editTextnewCity.length() == 0) cityName = (EditText) findViewById(R.id.editTextNewCity);
final String newCityString = cityName.getEditableText().toString();
if(newCityString.length() == 0)
{ {
editTextnewCity.setError("Please, enter a city name"); cityName.setError("Please, enter a city name");
} }
else else
System.out.println(newCity); saveCity(newCityString);
//Ajoute la ville a une base de données resetForm();
//Prélève le texte avec le get
//S'il est vide on l'alert et on fais rien
//Sinon écran d'accueil qui change
} }
}); });
} }
private void resetForm()
{
cityName.setText(null);
}
private void saveCity(String cityName)
{
CityRepository.getInstance(this).addCity(new City(cityName));
}
} }

View File

@ -0,0 +1,32 @@
package fr.romanet.vj.apps.myweather;
import java.util.List;
import fr.romanet.vj.apps.myweather.bo.City;
//Interface used in order to implement correctly the repository pattern
public interface ICityService
{
/**
* Get all the city
* @return {@link List}
*/
List<City> getCity();
/**
* Deletes a city
* @param cityToDelete
*/
void deleteCity(City cityToDelete);
/**
* Add a city
* @param cityToAdd
*/
void addCity(City cityToAdd);
/**
* Get all cities sorted by name
* @return {@link List}
*/
List<City> sortCityByName();
}

View File

@ -2,11 +2,8 @@ package fr.romanet.vj.apps.myweather;
import android.content.*; import android.content.*;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {

View File

@ -0,0 +1,82 @@
package fr.romanet.vj.apps.myweather.bo;
import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Objects;
//This class is used in order to represent a city
@Entity
final public class City implements Serializable
{
//Class CityComparator that implements Comparator interface in order to compare two cities
public static final class CityComparator implements Comparator<City>
{
/**
* Compare function that compare two city by their name
* @param o1 The first city to compare
* @param o2 Second city to compare with the first
* @return
*/
@Override
public int compare(City o1, City o2)
{
return o1.nameCity.compareTo(o2.nameCity);
}
}
/**
* The primary key of the city in our datbase which is automatically incremented
*/
@PrimaryKey(autoGenerate = true)
public int id;
/**
* The name of the city
*/
@NonNull
public String nameCity;
/**
* Constructor of the city class
* @param nameCity The name of the new city
*/
public City(@NonNull String nameCity)
{
id = 0;
this.nameCity = nameCity;
}
/**
* Equals function that return true or false weither both name are same and both object belongs to City class
* @param o The object to compare
* @return true or false
*/
@Override
public boolean equals(Object o) {
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
City city1 = (City) o;
return nameCity.equals(city1.nameCity);
}
/**
* hashCode function
* @return Clé de hashage (int)
*/
@Override
public int hashCode()
{
return Objects.hash(nameCity);
}
}

View File

@ -0,0 +1,30 @@
package fr.romanet.vj.apps.myweather.dao;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import fr.romanet.vj.apps.myweather.ICityService;
import fr.romanet.vj.apps.myweather.bo.City;
import java.util.List;
@Dao
public interface CityDao extends ICityService
{
@Override
@Query("SELECT * FROM City")
List<City> getCity();
@Override
@Delete
void deleteCity(City cityToDelete);
@Override
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addCity(City cityToAdd);
@Override
@Query("SELECT * FROM City ORDER BY nameCity DESC")
List<City> sortCityByName();
}

View File

@ -0,0 +1,13 @@
package fr.romanet.vj.apps.myweather.database;
import androidx.room.Database;
import androidx.room.RoomDatabase;
import fr.romanet.vj.apps.myweather.bo.City;
import fr.romanet.vj.apps.myweather.dao.CityDao;
@Database(entities = { City.class }, version = 1)
public abstract class CityDatabase extends RoomDatabase
{
public abstract CityDao cityDao();
}

View File

@ -0,0 +1,56 @@
package fr.romanet.vj.apps.myweather.repository;
import android.content.Context;
import androidx.room.Room;
import java.util.List;
import fr.romanet.vj.apps.myweather.bo.City;
import fr.romanet.vj.apps.myweather.database.CityDatabase;
public final class CityRepository
{
private static volatile CityRepository instance;
// We accept the "out-of-order writes" case
public static CityRepository getInstance(Context context)
{
if (instance == null)
{
synchronized (CityRepository.class)
{
if (instance == null)
{
instance = new CityRepository(context);
}
}
}
return instance;
}
private final CityDatabase cityDatabase;
private CityRepository(Context context)
{
cityDatabase = Room.databaseBuilder(context, CityDatabase.class, "city-database").allowMainThreadQueries().build();
}
public List<City> getCity()
{
return cityDatabase.cityDao().getCity();
}
public void deleteCity(City cityToDelete)
{
cityDatabase.cityDao().deleteCity(cityToDelete);
}
public void addCity(City cityToAdd)
{
cityDatabase.cityDao().addCity(cityToAdd);
}
public List<City> sortCityByName()
{
return cityDatabase.cityDao().sortCityByName();
}
}