Completed 5, 6, 7 tasks
This commit is contained in:
parent
e65180b143
commit
39447cc237
@ -15,6 +15,12 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.AirQuality"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".SearchCityActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".FavoritesActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".DetailsActivity"
|
||||
android:exported="false" />
|
||||
|
||||
@ -5,12 +5,6 @@ import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
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.android.volley.RequestQueue;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
@ -18,16 +12,10 @@ import com.bumptech.glide.Glide;
|
||||
import com.example.airquality.api.ForecastAPIRequest;
|
||||
import com.example.airquality.databinding.ActivityDetailsBinding;
|
||||
import com.example.airquality.types.City;
|
||||
import com.example.airquality.types.FormattedTemp;
|
||||
import com.example.airquality.types.FormattedTemperature;
|
||||
import com.example.airquality.types.Weather3h;
|
||||
import com.example.airquality.utils.PreferencesManager;
|
||||
import com.example.airquality.utils.ToolbarCompatActivity;
|
||||
import com.example.airquality.utils.Weather3hAdapter;
|
||||
import com.example.airquality.utils.Weather3hParser;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DetailsActivity extends ToolbarCompatActivity {
|
||||
|
||||
@ -54,7 +42,7 @@ public class DetailsActivity extends ToolbarCompatActivity {
|
||||
}
|
||||
|
||||
protected void updateData() {
|
||||
FormattedTemp formattedTemp = weather3h.formattedTemp(this);
|
||||
FormattedTemperature formattedTemperature = weather3h.formattedTemp(this);
|
||||
|
||||
if(checkInternet())
|
||||
{
|
||||
@ -70,10 +58,10 @@ public class DetailsActivity extends ToolbarCompatActivity {
|
||||
binding.iconCode.setText(weather3h.getIconCode());
|
||||
}
|
||||
|
||||
binding.cityText.setText(city.name);
|
||||
binding.cityText.setText(city.toString());
|
||||
binding.datetimeText.setText(weather3h.getDateTime());
|
||||
binding.tempWeatherText.setText(formattedTemp.tempText + " | " + weather3h.getDescription());
|
||||
binding.tempText.setText(formattedTemp.tempMinText + " ~ " + formattedTemp.tempMaxText);
|
||||
binding.tempWeatherText.setText(formattedTemperature.tempText + " | " + weather3h.getDescription());
|
||||
binding.tempText.setText(formattedTemperature.tempMinText + " ~ " + formattedTemperature.tempMaxText);
|
||||
binding.pressureText.setText(weather3h.getPressure() + " hPa");
|
||||
binding.humidityText.setText(weather3h.getHumidity() + "%");
|
||||
binding.windSpeedText.setText(weather3h.getWindSpeed() + " m/s");
|
||||
@ -81,6 +69,11 @@ public class DetailsActivity extends ToolbarCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onRefreshOptionToolbar() {
|
||||
if(!checkInternet()) {
|
||||
Toast.makeText(this, "You can't load data from internet on offline mode", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
String units = PreferencesManager.getUnits(this);
|
||||
RequestQueue queue = Volley.newRequestQueue(this);
|
||||
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
package com.example.airquality;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
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 androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.example.airquality.databinding.ActivityFavoritesBinding;
|
||||
import com.example.airquality.types.City;
|
||||
import com.example.airquality.utils.BaseCompatActivity;
|
||||
import com.example.airquality.utils.CityAdapter;
|
||||
import com.example.airquality.utils.PreferencesManager;
|
||||
import com.example.airquality.utils.Weather3hAdapter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class FavoritesActivity extends BaseCompatActivity {
|
||||
|
||||
private ActivityFavoritesBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
|
||||
binding = ActivityFavoritesBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
|
||||
binding.cityFavoriteList.setLayoutManager(new LinearLayoutManager(this));
|
||||
}
|
||||
public void onSearchActivityBtn(View view) {
|
||||
Intent intent = new Intent(this, SearchCityActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
loadFavoriteList();
|
||||
}
|
||||
private City[] getFavoriteList()
|
||||
{
|
||||
// Get from db
|
||||
City[] cities = new City[] {
|
||||
new City("Belgrade", "RS", 44.7866, 20.4489, "2025-07-04 12:30"),
|
||||
new City("Novi Sad", "RS", 45.2671, 19.8335, "2025-07-03 09:15"),
|
||||
new City("Niš", "RS", 43.3209, 21.8958, "2025-07-02 18:45"),
|
||||
new City("Subotica", "RS", 46.1000, 19.6667, "2025-07-01 14:10"),
|
||||
new City("Kragujevac", "RS", 44.0128, 20.9110, "2025-06-30 07:50")
|
||||
};
|
||||
|
||||
return cities;
|
||||
}
|
||||
private void setEnteredDateTime(City city) {
|
||||
// Search one item by city.name and change for him enteredAt to now()
|
||||
|
||||
}
|
||||
|
||||
private void loadFavoriteList() {
|
||||
List<City> cities = Arrays.asList(getFavoriteList());
|
||||
|
||||
CityAdapter adapter = new CityAdapter(this, cities) {
|
||||
@Override
|
||||
public void onSelectCity(City city) {
|
||||
PreferencesManager.setCity(FavoritesActivity.this, city);
|
||||
setEnteredDateTime(city);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
binding.cityFavoriteList.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,15 @@
|
||||
package com.example.airquality;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuInflater;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.volley.Request;
|
||||
import com.android.volley.RequestQueue;
|
||||
import com.android.volley.Response;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.android.volley.toolbox.JsonObjectRequest;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
import com.example.airquality.api.ForecastAPIRequest;
|
||||
import com.example.airquality.types.City;
|
||||
@ -25,30 +17,15 @@ import com.example.airquality.types.Weather3h;
|
||||
import com.example.airquality.utils.PreferencesManager;
|
||||
import com.example.airquality.utils.ToolbarCompatActivity;
|
||||
import com.example.airquality.utils.Weather3hAdapter;
|
||||
import com.example.airquality.utils.Weather3hParser;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MainActivity extends ToolbarCompatActivity {
|
||||
List<Weather3h> prognoza;
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
|
||||
private static final Map<String, double[]> cityCoordinates = new HashMap<>();
|
||||
static {
|
||||
cityCoordinates.put("Subotica", new double[]{46.1, 19.6667});
|
||||
cityCoordinates.put("Novi Sad", new double[]{45.2517, 19.8369});
|
||||
cityCoordinates.put("Beograd", new double[]{44.804, 20.4651});
|
||||
cityCoordinates.put("San Francisko", new double[]{37.7749, -122.4194});
|
||||
cityCoordinates.put("Sidnej", new double[]{-33.8679, 151.2073});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -61,13 +38,26 @@ public class MainActivity extends ToolbarCompatActivity {
|
||||
initToolbar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
loadForecast();
|
||||
}
|
||||
|
||||
private void saveOffline(Weather3h[] weathers) {
|
||||
// Save to db
|
||||
}
|
||||
private Weather3h[] loadOffline() {
|
||||
// Load from db
|
||||
return new Weather3h[] { };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRefreshOptionToolbar() {
|
||||
if(!checkInternet()) {
|
||||
Toast.makeText(MainActivity.this, "You can't load data from internet on offline mode", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
loadForecast(true);
|
||||
}
|
||||
|
||||
@ -79,10 +69,18 @@ public class MainActivity extends ToolbarCompatActivity {
|
||||
int days = PreferencesManager.getDays(this);
|
||||
String units = PreferencesManager.getUnits(this);
|
||||
|
||||
setToolbarTitle(city.name);
|
||||
|
||||
if (city == null) {
|
||||
Toast.makeText(this, "Unknown city: " + city.name, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, "Unknown city", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
setToolbarTitle(city.toString());
|
||||
|
||||
// If no internet
|
||||
if(!checkInternet()) {
|
||||
displayRecycler(loadOffline(), city, days);
|
||||
Toast.makeText(MainActivity.this, "You are on offline mode", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -91,14 +89,12 @@ public class MainActivity extends ToolbarCompatActivity {
|
||||
ForecastAPIRequest forecastAPI = new ForecastAPIRequest(this, city, units) {
|
||||
@Override
|
||||
public void onSuccess(Weather3h[] weatherList) {
|
||||
Weather3h[] arr = Arrays.copyOfRange(weatherList, 0, days);
|
||||
prognoza = Arrays.asList(arr);
|
||||
|
||||
Weather3hAdapter adapter = new Weather3hAdapter(MainActivity.this, prognoza, city);
|
||||
recyclerView.setAdapter(adapter);
|
||||
displayRecycler(weatherList, city, days);
|
||||
|
||||
if(isUpdated)
|
||||
Toast.makeText(MainActivity.this, "List Updated!", Toast.LENGTH_SHORT).show();
|
||||
|
||||
saveOffline(weatherList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -109,4 +105,16 @@ public class MainActivity extends ToolbarCompatActivity {
|
||||
|
||||
queue.add(forecastAPI.getRequest());
|
||||
}
|
||||
private void displayRecycler(Weather3h[] weathers, City city, int days) {
|
||||
if(weathers.length > 0) {
|
||||
Weather3h[] weatherDaysRange = Arrays.copyOfRange(weathers, 0, days * 8);
|
||||
prognoza = Arrays.asList(weatherDaysRange);
|
||||
}
|
||||
else {
|
||||
prognoza.clear();
|
||||
}
|
||||
|
||||
Weather3hAdapter adapter = new Weather3hAdapter(this, prognoza, city);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.example.airquality;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
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 androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.android.volley.RequestQueue;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
import com.example.airquality.api.CityAPIRequest;
|
||||
import com.example.airquality.databinding.ActivitySearchCityBinding;
|
||||
import com.example.airquality.types.City;
|
||||
import com.example.airquality.utils.BaseCompatActivity;
|
||||
import com.example.airquality.utils.CityAdapter;
|
||||
import com.example.airquality.utils.PreferencesManager;
|
||||
import com.example.airquality.utils.Weather3hAdapter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SearchCityActivity extends BaseCompatActivity {
|
||||
|
||||
private ActivitySearchCityBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
|
||||
binding = ActivitySearchCityBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
binding.citySearchResult.setLayoutManager(new LinearLayoutManager(this));
|
||||
}
|
||||
|
||||
public void onSearchBtn(View view) {
|
||||
loadCities();
|
||||
}
|
||||
|
||||
private void addToFavorite(City city) {
|
||||
// Add to db
|
||||
}
|
||||
|
||||
private void loadCities() {
|
||||
String searchQuery = binding.searchEditText.getText().toString();
|
||||
|
||||
// If no internet
|
||||
if(!checkInternet()) {
|
||||
Toast.makeText(this, "You are on offline mode", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
RequestQueue queue = Volley.newRequestQueue(this);
|
||||
|
||||
CityAPIRequest cityAPIRequest = new CityAPIRequest(this, searchQuery) {
|
||||
@Override
|
||||
public void onSuccess(City[] objectList) {
|
||||
CityAdapter adapter = new CityAdapter(SearchCityActivity.this, Arrays.asList(objectList), "Add") {
|
||||
@Override
|
||||
public void onSelectCity(City city) {
|
||||
addToFavorite(city);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
binding.citySearchResult.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError error) {
|
||||
Toast.makeText(SearchCityActivity.this, "Failed to load weather data", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
|
||||
queue.add(cityAPIRequest.getRequest());
|
||||
}
|
||||
}
|
||||
@ -7,47 +7,35 @@ import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
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.example.airquality.types.City;
|
||||
import com.example.airquality.utils.BaseCompatActivity;
|
||||
import com.example.airquality.utils.PreferencesManager;
|
||||
|
||||
public class SettingsActivity extends BaseCompatActivity {
|
||||
Spinner spinnerCity;
|
||||
RadioGroup radioGroupDays, radioGroupUnits;
|
||||
Button buttonSave;
|
||||
|
||||
String[] cities = {"Subotica", "Novi Sad", "Beograd", "San Francisko", "Sidnej"};
|
||||
TextView cityNameText;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
|
||||
spinnerCity = findViewById(R.id.spinnerCity);
|
||||
radioGroupDays = findViewById(R.id.radioGroupDays);
|
||||
radioGroupUnits = findViewById(R.id.radioGroupUnits);
|
||||
buttonSave = findViewById(R.id.buttonSave);
|
||||
|
||||
// Podesi spinner
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_spinner_item, cities);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinnerCity.setAdapter(adapter);
|
||||
cityNameText = findViewById(R.id.cityName);
|
||||
|
||||
buttonSave.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
String selectedCity = spinnerCity.getSelectedItem().toString();
|
||||
|
||||
int days = 7; // podrazumevano
|
||||
int days = 1; // podrazumevano
|
||||
if (radioGroupDays.getCheckedRadioButtonId() == R.id.radio3days) {
|
||||
days = 3;
|
||||
} else if (radioGroupDays.getCheckedRadioButtonId() == R.id.radio5days) {
|
||||
@ -59,15 +47,22 @@ public class SettingsActivity extends BaseCompatActivity {
|
||||
units = "imperial";
|
||||
}
|
||||
|
||||
SharedPreferences prefs = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putString("city", selectedCity);
|
||||
editor.putInt("days", days);
|
||||
editor.putString("units", units);
|
||||
editor.apply();
|
||||
PreferencesManager.savePreferences(SettingsActivity.this, days, units);
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onFavoriteBtn(View view) {
|
||||
Intent intent = new Intent(this, FavoritesActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
City currentCity = PreferencesManager.getCity(this);
|
||||
cityNameText.setText(currentCity.toString());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package com.example.airquality.api;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.volley.Request;
|
||||
import com.android.volley.Response;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.android.volley.toolbox.JsonArrayRequest;
|
||||
import com.android.volley.toolbox.JsonObjectRequest;
|
||||
import com.example.airquality.types.City;
|
||||
import com.example.airquality.utils.CityParser;
|
||||
import com.example.airquality.utils.Weather3hParser;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class CityAPIRequest extends JsonAPIRequest<City, JsonArrayRequest> {
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public CityAPIRequest(Context context, String query) {
|
||||
super(context);
|
||||
this.url = String.format(
|
||||
"https://api.openweathermap.org/geo/1.0/direct?q=%s&limit=10&appid=%s",
|
||||
query, getKey()
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public JsonArrayRequest getRequest() {
|
||||
return new JsonArrayRequest(
|
||||
Request.Method.GET,
|
||||
url,
|
||||
null,
|
||||
new Response.Listener<JSONArray>() {
|
||||
@Override
|
||||
public void onResponse(JSONArray response) {
|
||||
onSuccess(CityParser.parse(response));
|
||||
}
|
||||
},
|
||||
new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
error.printStackTrace();
|
||||
onError(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(City[] objectList) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError error) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ import org.json.JSONObject;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ForecastAPIRequest extends JsonAPIRequest {
|
||||
public class ForecastAPIRequest extends JsonAPIRequest<Weather3h, JsonObjectRequest> {
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public ForecastAPIRequest(Context context, City city, String units) {
|
||||
@ -49,6 +49,6 @@ public class ForecastAPIRequest extends JsonAPIRequest {
|
||||
);
|
||||
}
|
||||
|
||||
public void onSuccess(Weather3h[] weatherList) { }
|
||||
public void onSuccess(Weather3h[] objectList) { }
|
||||
public void onError(VolleyError error) { }
|
||||
}
|
||||
@ -9,12 +9,13 @@ import com.android.volley.VolleyError;
|
||||
import com.android.volley.toolbox.JsonObjectRequest;
|
||||
import com.example.airquality.MainActivity;
|
||||
import com.example.airquality.R;
|
||||
import com.example.airquality.types.Weather3h;
|
||||
import com.example.airquality.utils.Weather3hAdapter;
|
||||
import com.example.airquality.utils.Weather3hParser;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public abstract class JsonAPIRequest {
|
||||
public abstract class JsonAPIRequest<T, JR> {
|
||||
|
||||
private Context appContext;
|
||||
protected String url;
|
||||
@ -28,5 +29,8 @@ public abstract class JsonAPIRequest {
|
||||
{
|
||||
return this.appContext.getString(R.string.weather_api_key);
|
||||
}
|
||||
public abstract JsonObjectRequest getRequest();
|
||||
public abstract JR getRequest();
|
||||
|
||||
public abstract void onSuccess(T[] objectList);
|
||||
public abstract void onError(VolleyError error);
|
||||
}
|
||||
|
||||
@ -1,15 +1,30 @@
|
||||
package com.example.airquality.types;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class City implements Serializable {
|
||||
public String name;
|
||||
public String country;
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public String lastEnteredAt;
|
||||
|
||||
public City(String name, double latitude, double longitude) {
|
||||
public City(String name, String country, double latitude, double longitude, String lastEnteredAt) {
|
||||
this.name = name;
|
||||
this.country = country;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.lastEnteredAt = lastEnteredAt;
|
||||
}
|
||||
public City(String name, String country, double latitude, double longitude) {
|
||||
this(name, country, latitude, longitude, "");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name + " (" + this.country + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,18 +2,14 @@ package com.example.airquality.types;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.example.airquality.utils.PreferencesManager;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FormattedTemp {
|
||||
public class FormattedTemperature {
|
||||
public String tempText;
|
||||
public String tempMinText;
|
||||
public String tempMaxText;
|
||||
|
||||
public FormattedTemp(Context context, double temp, double tempMin, double tempMax)
|
||||
public FormattedTemperature(Context context, double temp, double tempMin, double tempMax)
|
||||
{
|
||||
String units = PreferencesManager.getUnits(context);
|
||||
|
||||
@ -49,8 +49,8 @@ public class Weather3h implements Serializable {
|
||||
return tempMax;
|
||||
}
|
||||
|
||||
public FormattedTemp formattedTemp(Context context) {
|
||||
return new FormattedTemp(context, temp, tempMin, tempMax);
|
||||
public FormattedTemperature formattedTemp(Context context) {
|
||||
return new FormattedTemperature(context, temp, tempMin, tempMax);
|
||||
}
|
||||
|
||||
public int getDt() {
|
||||
|
||||
@ -3,6 +3,7 @@ package com.example.airquality.utils;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
@ -13,4 +14,9 @@ public class BaseCompatActivity extends AppCompatActivity {
|
||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
|
||||
}
|
||||
|
||||
public void onBackButton(View view)
|
||||
{
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
package com.example.airquality.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.airquality.R;
|
||||
import com.example.airquality.types.City;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CityAdapter extends RecyclerView.Adapter<CityAdapter.CityViewHolder> {
|
||||
|
||||
private Context context;
|
||||
private List<City> cityList;
|
||||
private String applyBtnText;
|
||||
|
||||
public CityAdapter(Context context, List<City> cityList) {
|
||||
this(context, cityList, "Select");
|
||||
}
|
||||
public CityAdapter(Context context, List<City> cityList, String applyBtnText) {
|
||||
this.context = context;
|
||||
this.cityList = cityList;
|
||||
this.applyBtnText = applyBtnText;
|
||||
}
|
||||
public static class CityViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView cityName, cityCoords, lastEnteredTime;
|
||||
Button selectBtn;
|
||||
|
||||
public CityViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
cityName = itemView.findViewById(R.id.cityName);
|
||||
cityCoords = itemView.findViewById(R.id.cityCoords);
|
||||
selectBtn = itemView.findViewById(R.id.selectBtn);
|
||||
lastEnteredTime = itemView.findViewById(R.id.lastEnteredTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CityViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.item_city, parent, false);
|
||||
return new CityViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(CityViewHolder holder, int position) {
|
||||
City item = cityList.get(position);
|
||||
holder.cityName.setText(item.toString());
|
||||
holder.cityCoords.setText(
|
||||
"Long: " + String.format("%.3f", item.longitude) + ", Lat: " + String.format("%.3f", item.latitude));
|
||||
holder.lastEnteredTime.setText(item.lastEnteredAt);
|
||||
|
||||
holder.selectBtn.setText(this.applyBtnText);
|
||||
|
||||
holder.selectBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onSelectCity(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cityList.size();
|
||||
}
|
||||
|
||||
public void onSelectCity(City city) { }
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.example.airquality.utils;
|
||||
|
||||
import com.example.airquality.types.City;
|
||||
import com.example.airquality.types.Weather3h;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CityParser {
|
||||
public static City[] parse(JSONArray jsonArray) {
|
||||
List<City> cities = new ArrayList<>();
|
||||
|
||||
try {
|
||||
for(int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
|
||||
String cityName = jsonObject.getString("name");
|
||||
double lon = jsonObject.getDouble("lon");
|
||||
double lat = jsonObject.getDouble("lat");
|
||||
String countryName = jsonObject.getString("country");
|
||||
|
||||
City city = new City(cityName, countryName, lat, lon);
|
||||
cities.add(city);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return cities.toArray(new City[0]);
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ public class PreferencesManager {
|
||||
private static final String KEY_DAYS = "days";
|
||||
private static final String KEY_UNITS = "units";
|
||||
|
||||
public static void savePreferences(Context context, String city, int days, String units) {
|
||||
public static void savePreferences(Context context, int days, String units) {
|
||||
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putInt(KEY_DAYS, days);
|
||||
@ -20,13 +20,28 @@ public class PreferencesManager {
|
||||
}
|
||||
|
||||
public static City getCity(Context context) {
|
||||
// DAVID: Realizovati iz sqlite
|
||||
return new City("Subotica", 46.1, 19.6667);
|
||||
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||
String cityName = prefs.getString("city_name", "Subotica");
|
||||
String country = prefs.getString("city_country", "RS");
|
||||
double longitude = prefs.getFloat("city_longitude", 46.1f);
|
||||
double latitude = prefs.getFloat("city_latitude", 19.6667f);
|
||||
|
||||
return new City(cityName, country, longitude, latitude);
|
||||
}
|
||||
public static void setCity(Context context, City city) {
|
||||
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
|
||||
editor.putString("city_name", city.name);
|
||||
editor.putString("city_country", city.country);
|
||||
editor.putFloat("city_longitude", (float)city.longitude);
|
||||
editor.putFloat("city_latitude", (float)city.latitude);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static int getDays(Context context) {
|
||||
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||
return prefs.getInt(KEY_DAYS, 7); // default: 7 dana
|
||||
return prefs.getInt(KEY_DAYS, 1); // default: 1 dana
|
||||
}
|
||||
|
||||
public static String getUnits(Context context) {
|
||||
|
||||
@ -5,17 +5,14 @@ import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.airquality.DetailsActivity;
|
||||
import com.example.airquality.MainActivity;
|
||||
import com.example.airquality.R;
|
||||
import com.example.airquality.types.City;
|
||||
import com.example.airquality.types.FormattedTemp;
|
||||
import com.example.airquality.types.FormattedTemperature;
|
||||
import com.example.airquality.types.Weather3h;
|
||||
|
||||
import java.util.List;
|
||||
@ -31,8 +28,6 @@ public class Weather3hAdapter extends RecyclerView.Adapter<Weather3hAdapter.Weat
|
||||
this.weatherList = weatherList;
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
// ViewHolder описывает и хранит ссылки на элементы layout
|
||||
public static class WeatherViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView txtDate, txtTemp, txtDesc;
|
||||
|
||||
@ -53,10 +48,10 @@ public class Weather3hAdapter extends RecyclerView.Adapter<Weather3hAdapter.Weat
|
||||
@Override
|
||||
public void onBindViewHolder(WeatherViewHolder holder, int position) {
|
||||
Weather3h item = weatherList.get(position);
|
||||
FormattedTemp formattedTemp = item.formattedTemp(context);
|
||||
FormattedTemperature formattedTemperature = item.formattedTemp(context);
|
||||
|
||||
holder.txtDate.setText(item.getDateTime());
|
||||
holder.txtTemp.setText(formattedTemp.tempText);
|
||||
holder.txtTemp.setText(formattedTemperature.tempText);
|
||||
holder.txtDesc.setText(item.getDescription());
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
5
app/src/main/res/drawable/baseline_arrow_back.xml
Normal file
5
app/src/main/res/drawable/baseline_arrow_back.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
|
||||
</vector>
|
||||
@ -17,6 +17,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/include_toolbar"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:background="@color/white"
|
||||
android:padding="20dp"
|
||||
>
|
||||
|
||||
@ -57,12 +58,9 @@
|
||||
>
|
||||
|
||||
<TextView
|
||||
style="@style/headerText"
|
||||
android:id="@+id/cityText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="City name"
|
||||
android:textStyle="bold"
|
||||
android:textSize="20sp"/>
|
||||
android:text="City name"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/datetimeText"
|
||||
|
||||
54
app/src/main/res/layout/activity_favorites.xml
Normal file
54
app/src/main/res/layout/activity_favorites.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?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:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:background="@color/white"
|
||||
tools:context=".FavoritesActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<Button
|
||||
style="@style/BackButton"
|
||||
android:onClick="onBackButton" />
|
||||
|
||||
<TextView
|
||||
style="@style/headerText"
|
||||
android:text="Favorite cities" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/newCityBtn"
|
||||
style="@style/GreenButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="320dp"
|
||||
android:text="Add new city"
|
||||
android:layout_marginTop="20dp"
|
||||
android:onClick="onSearchActivityBtn"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/cityFavoriteList"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:dividerHeight="1dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/newCityBtn"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
72
app/src/main/res/layout/activity_search_city.xml
Normal file
72
app/src/main/res/layout/activity_search_city.xml
Normal file
@ -0,0 +1,72 @@
|
||||
<?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:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:background="@color/white"
|
||||
tools:context=".SearchCityActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<Button
|
||||
style="@style/BackButton"
|
||||
android:onClick="onBackButton" />
|
||||
|
||||
<TextView
|
||||
style="@style/headerText"
|
||||
android:text="Search city" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/fieldset"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/linearLayout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/searchEditText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toStartOf="@+id/searchBtn"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
style="@style/GreenButtonStyle"
|
||||
android:id="@+id/searchBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Search"
|
||||
android:onClick="onSearchBtn"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/citySearchResult"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:dividerHeight="1dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/fieldset"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@ -2,6 +2,7 @@
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:padding="16dp"
|
||||
android:background="@color/white">
|
||||
|
||||
@ -10,9 +11,24 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<Button
|
||||
style="@style/BackButton"
|
||||
android:onClick="onBackButton"
|
||||
/>
|
||||
<TextView
|
||||
style="@style/headerText"
|
||||
android:text="Settings"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- GRAD -->
|
||||
<TextView
|
||||
android:text="Choose City:"
|
||||
android:text="City"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#444444"
|
||||
@ -20,24 +36,37 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCity"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:spinnerMode="dropdown"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
android:popupBackground="@color/green_popup"/>
|
||||
<TextView
|
||||
android:id="@+id/cityName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="City name"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/selectCityBtn"
|
||||
style="@style/GreenSmallButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Select"
|
||||
android:onClick="onFavoriteBtn"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- separator -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="#0F9D58" />
|
||||
<include layout="@layout/component_settings_separator" />
|
||||
|
||||
<!-- BROJ DANA -->
|
||||
<TextView
|
||||
android:text="Forecast Duration:"
|
||||
android:text="Forecast Duration"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#444444"
|
||||
@ -49,6 +78,10 @@
|
||||
android:id="@+id/radioGroupDays"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<RadioButton android:id="@+id/radio1days"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="1 day" />
|
||||
<RadioButton android:id="@+id/radio3days"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -57,22 +90,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="5 days" />
|
||||
<RadioButton android:id="@+id/radio7days"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="7 days" />
|
||||
</RadioGroup>
|
||||
|
||||
<!-- separator -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="#0F9D58" />
|
||||
<include layout="@layout/component_settings_separator" />
|
||||
|
||||
<!-- JEDINICE -->
|
||||
<TextView
|
||||
android:text="Units:"
|
||||
android:text="Units"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#444444"
|
||||
@ -95,19 +120,14 @@
|
||||
</RadioGroup>
|
||||
|
||||
<!-- separator -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="#0F9D58" />
|
||||
<include layout="@layout/component_settings_separator" />
|
||||
|
||||
|
||||
<!-- DUGME -->
|
||||
<Button
|
||||
android:id="@+id/buttonSave"
|
||||
style="@style/GreenButtonStyle"
|
||||
android:text="Save and Return"
|
||||
android:textColor="@android:color/white"
|
||||
android:backgroundTint="#0F9D58"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
7
app/src/main/res/layout/component_settings_separator.xml
Normal file
7
app/src/main/res/layout/component_settings_separator.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<View
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="#0F9D58" />
|
||||
45
app/src/main/res/layout/item_city.xml
Normal file
45
app/src/main/res/layout/item_city.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cityName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Subotica"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cityCoords"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="long: 21.12, lat: 342.21"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cityName" />
|
||||
<TextView
|
||||
android:id="@+id/lastEnteredTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="20.12.2025 21:00:00"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cityCoords" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/selectBtn"
|
||||
style="@style/GreenSmallButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Select"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@ -5,5 +5,33 @@
|
||||
|
||||
</style>
|
||||
|
||||
<style name="BackButton">
|
||||
<item name="android:backgroundTint">#C5C5C5</item>
|
||||
<item name="android:drawableLeft">@drawable/baseline_arrow_back</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:minWidth">0dp</item>
|
||||
<item name="android:minHeight">0dp</item>
|
||||
<item name="android:layout_marginRight">15dp</item>
|
||||
<item name="android:textSize">20sp</item>
|
||||
</style>
|
||||
<style name="GreenButtonStyle">
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:backgroundTint">#0F9D58</item>
|
||||
</style>
|
||||
<style name="GreenSmallButtonStyle">
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:backgroundTint">#0F9D58</item>
|
||||
<item name="android:textSize">13sp</item>
|
||||
<item name="android:minWidth">0dp</item>
|
||||
<item name="android:minHeight">0dp</item>
|
||||
</style>
|
||||
<style name="headerText">
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textSize">24sp</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AirQuality" parent="Base.Theme.AirQuality" />
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user