Fix favourites list while all stations is still refreshing

fix/get-all-stations-hangout
Woloszyn Rafal 2022-05-04 13:25:51 +02:00 zatwierdzone przez rwoloszyn
rodzic 9d79ff9852
commit 27484a3002
13 zmienionych plików z 259 dodań i 105 usunięć

Wyświetl plik

@ -258,6 +258,7 @@ public class Main extends Application {
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void allStationsEventHandler(@NonNull AllStationsReceivedEvent event) {
this.listOfAllStations = event.getStations();
recreateListOfFavs();
}
public boolean listOfAllStationsReady() {

Wyświetl plik

@ -21,6 +21,7 @@ import cc.pogoda.mobile.meteosystem.R;
import cc.pogoda.mobile.meteosystem.adapter.WeatherStationRecyclerViewAdapter;
import cc.pogoda.mobile.meteosystem.type.AllStationsReceivedEvent;
import cc.pogoda.mobile.meteosystem.type.ParceableFavsCallReason;
import cc.pogoda.mobile.meteosystem.type.StartStationsRefreshEvent;
import cc.pogoda.mobile.meteosystem.type.WeatherStation;
public class AllStationsActivity extends AppCompatActivity {
@ -35,15 +36,9 @@ public class AllStationsActivity extends AppCompatActivity {
setContentView(R.layout.activity_all_stations);
refreshLayout = findViewById(R.id.refreshAllStationsView);
refreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
((Main) getApplication()).startGetAllStationsService();
}
}
() -> ((Main) getApplication()).startGetAllStationsService()
);
RecyclerView recyclerViewAllStations = findViewById(R.id.recyclerViewAllStations);
@ -51,14 +46,13 @@ public class AllStationsActivity extends AppCompatActivity {
allStationsList, this, ParceableFavsCallReason.Reason.ALL_STATIONS);
recyclerViewAllStations.setAdapter(adapter);
recyclerViewAllStations.setLayoutManager(new LinearLayoutManager(this));
updateStationList(((Main) getApplication()).getListOfAllStations());
}
@Override
protected void onResume() {
super.onResume();
EventBus.getDefault().register(this);
updateStationList(((Main) getApplication()).getListOfAllStations());
}
@Override
@ -67,15 +61,14 @@ public class AllStationsActivity extends AppCompatActivity {
EventBus.getDefault().unregister(this);
}
private void updateStationList(List<WeatherStation> stations){
private void updateStationList(List<WeatherStation> stations) {
if (stations != null) {
allStationsList.clear();
allStationsList.addAll(stations);
refreshLayout.setRefreshing(false);
adapter.notifyDataSetChanged();
} else {
refreshLayout.setRefreshing(true);
Toast.makeText(this,"Odświeżanie listy stacji", Toast.LENGTH_SHORT).show();
EventBus.getDefault().post(new StartStationsRefreshEvent());
}
}
@ -83,4 +76,10 @@ public class AllStationsActivity extends AppCompatActivity {
public void allStationsEventHandler(@NonNull AllStationsReceivedEvent event) {
updateStationList(event.getStations());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void startStationsRefreshEventHandler(@NonNull StartStationsRefreshEvent event) {
refreshLayout.setRefreshing(true);
Toast.makeText(this, R.string.refreshing_station_list, Toast.LENGTH_SHORT).show();
}
}

Wyświetl plik

@ -3,30 +3,43 @@ package cc.pogoda.mobile.meteosystem.activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import cc.pogoda.mobile.meteosystem.Main;
import cc.pogoda.mobile.meteosystem.R;
import cc.pogoda.mobile.meteosystem.adapter.WeatherStationRecyclerViewAdapter;
import cc.pogoda.mobile.meteosystem.type.AllStationsReceivedEvent;
import cc.pogoda.mobile.meteosystem.type.ParceableFavsCallReason;
import cc.pogoda.mobile.meteosystem.type.StartStationsRefreshEvent;
import cc.pogoda.mobile.meteosystem.type.WeatherStation;
public class FavouritesActivity extends AppCompatActivity {
Main main;
RecyclerView recyclerViewFavourites;
List<WeatherStation> favourites, sortedFavourites;
private SwipeRefreshLayout refreshLayout;
List<WeatherStation> favourites = new LinkedList<>();
List<WeatherStation> sortedFavourites;
boolean sorting = false;
@ -78,8 +91,6 @@ public class FavouritesActivity extends AppCompatActivity {
recyclerViewFavourites.setAdapter(adapter);
}
break;
case R.id.fav_remove_noext:
break;
}
@ -89,45 +100,65 @@ public class FavouritesActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
main = (Main)getApplication();
setContentView(R.layout.activity_favourites);
favourites = main.getFavs();
if(favourites == null){
return;
}
sortedFavourites = new ArrayList<>(favourites);
sortedFavourites.sort(new WxStationComparator());
recyclerViewFavourites = findViewById(R.id.recyclerViewFavourites);
refreshLayout = findViewById(R.id.refreshViewFavourites);
refreshLayout.setOnRefreshListener(
() -> ((Main) getApplication()).startGetAllStationsService()
);
callReason = getIntent().getParcelableExtra("callReason");
adapter = new WeatherStationRecyclerViewAdapter(favourites,
this, callReason.getReason());
recyclerViewFavourites.setAdapter(adapter);
recyclerViewFavourites.setLayoutManager(new LinearLayoutManager(this));
}
if (favourites == null || favourites.size() == 0) {
setContentView(R.layout.activity_favourites_empty);
}
else {
setContentView(R.layout.activity_favourites);
@Override
protected void onResume() {
super.onResume();
EventBus.getDefault().register(this);
updateStationList();
}
recyclerViewFavourites = findViewById(R.id.recyclerViewFavourites);
if (recyclerViewFavourites != null) {
adapter = new WeatherStationRecyclerViewAdapter(favourites, this, callReason.getReason());
adapter.createAndStartUpdater();
recyclerViewFavourites.setAdapter(adapter);
recyclerViewFavourites.setLayoutManager(new LinearLayoutManager(this));
}
}
@Override
protected void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
}
@Override
protected void onDestroy() {
adapter.stopUpdater();
super.onDestroy();
}
if (adapter != null) {
adapter.stopUpdater();
private void updateStationList() {
List favList = ((Main) getApplication()).getFavs();
if(favList != null) {
favourites.clear();
favourites.addAll(favList);
refreshLayout.setRefreshing(false);
sortedFavourites = new ArrayList<>(favourites);
sortedFavourites.sort(new WxStationComparator());
adapter.notifyDataSetChanged();
if (!favList.isEmpty()) {
adapter.createAndStartUpdater();
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void allStationsEventHandler(@NonNull AllStationsReceivedEvent event) {
updateStationList();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void startStationsRefreshEventHandler(@NonNull StartStationsRefreshEvent event) {
refreshLayout.setRefreshing(true);
Toast.makeText(this, R.string.refreshing_station_list, Toast.LENGTH_SHORT).show();
}
}

Wyświetl plik

@ -92,15 +92,17 @@ public class FavouritesStationDetailsOnListUpdater implements Runnable {
// query web service for station data
Summary summary = stationNameSummary.get(stationSystemName);
Logger.debug("[FavouritesStationDetailsOnListUpdater][run][stationSystemName = " + stationSystemName +"][summary.last_timestamp = " + summary.last_timestamp +"]");
// query for available parameters
AvailableParametersWeb params = availableParametersDao.getAvaliableParamsByStationName(stationSystemName);
AvailableParametersWeb params
= availableParametersDao.getAvaliableParamsByStationName(stationSystemName);
// if data has been collected
if (summary != null) {
String str;
Logger.debug("[FavouritesStationDetailsOnListUpdater][run][stationSystemName = " +
"" + stationSystemName +"][summary.last_timestamp = " + summary.last_timestamp +"]");
// check if this station transmits wind information
if (params.hasWind) {

Wyświetl plik

@ -26,9 +26,9 @@ import cc.pogoda.mobile.meteosystem.dao.SummaryDao;
import cc.pogoda.mobile.meteosystem.type.ParceableFavsCallReason;
import cc.pogoda.mobile.meteosystem.type.WeatherStation;
public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllStationsActRecyclerViewHolder> {
public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<WeatherStation> stations;
final private List<WeatherStation> stations;
AppCompatActivity activity;
@ -51,7 +51,13 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
*/
Main main;
public WeatherStationRecyclerViewAdapter(List<WeatherStation> stations, AppCompatActivity parentActivity, ParceableFavsCallReason.Reason callReason) {
private static final int VIEW_TYPE_EMPTY_LIST = 0;
private static final int VIEW_TYPE_OBJECT = 1;
public WeatherStationRecyclerViewAdapter(
List<WeatherStation> stations,
AppCompatActivity parentActivity,
ParceableFavsCallReason.Reason callReason) {
this.stations = stations;
this.activity = parentActivity;
this.reason = callReason;
@ -62,77 +68,95 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
@NonNull
@Override
public AllStationsActRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view;
// check the call reason
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
// inflate custom layout
view = inflater.inflate(R.layout.activity_favourites_linear_layout_data, parent, false);
}
else {
// Inflate the custom layout without current data
view = inflater.inflate(R.layout.activity_all_stations_linear_layout, parent, false);
}
switch (viewType){
case VIEW_TYPE_OBJECT:
// check the call reason
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
// inflate custom layout
view = inflater.inflate(R.layout.activity_favourites_linear_layout_data,
parent, false);
}
else {
// Inflate the custom layout without current data
view = inflater.inflate(R.layout.activity_all_stations_linear_layout,
parent, false);
}
return new AllStationsActRecyclerViewHolder(view, reason);
// Return a new holder instance
AllStationsActRecyclerViewHolder viewHolder = new AllStationsActRecyclerViewHolder(view, reason);
return viewHolder;
case VIEW_TYPE_EMPTY_LIST:
default:
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
view = inflater.inflate(R.layout.activity_favourites_empty, parent,
false);
} else {
view = inflater.inflate(R.layout.activity_all_stations_empty, parent,
false);
}
return new EmptyViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull AllStationsActRecyclerViewHolder holder, int position) {
// this TextView shows the station name
TextView textView = holder.textView;
public int getItemViewType(int position) {
if (stations.isEmpty()) {
return VIEW_TYPE_EMPTY_LIST;
} else {
return VIEW_TYPE_OBJECT;
}
}
// this TextView shows station data if this is favourites list
TextView textViewData = holder.textViewData;
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
// button to go to the StationDetailsActivity
Button button = holder.button;
if(viewHolder instanceof AllStationsActRecyclerViewHolder) {
AllStationsActRecyclerViewHolder holder =
(AllStationsActRecyclerViewHolder) viewHolder;
// get the station object from a list of either all stations or favourites
WeatherStation station = stations.get(position);
// this TextView shows the station name
TextView textView = holder.textView;
if (station != null) {
textView.setText(station.getDisplayedName());
button.setText(R.string.select_station);
// this TextView shows station data if this is favourites list
TextView textViewData = holder.textViewData;
// button to go to the StationDetailsActivity
Button button = holder.button;
// get the station object from a list of either all stations or favourites
WeatherStation station = stations.get(position);
if (station != null) {
textView.setText(station.getDisplayedName());
button.setText(R.string.select_station);
if (!reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
if (station.getDisplayedName().length() > 22) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20.0f);
} else {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22.0f);
}
}
else {
if (station.getDisplayedName().length() > 22) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20.0f);
} else {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22.0f);
}
button.setOnClickListener(new AllStationsActRecyclerViewButtonClickEvent(station, activity, reason));
}
button.setOnClickListener(new AllStationsActRecyclerViewButtonClickEvent(station, activity, reason));
// this if distinguish between All Stations and Favorites view
if (textViewData != null && favsUpdater != null) {
favsUpdater.addNewStation(station.getSystemName(), textViewData);
}
}
// this if distinguish between All Stations and Favorites view
if (textViewData != null && favsUpdater != null) {
favsUpdater.addNewStation(station.getSystemName(), textViewData);
}
}
@Override
public int getItemCount() {
return stations.size();
// In case of empty station list at least 1 should be returned to properly select view type
// and render empty list info.
return stations.isEmpty() ? 1 : stations.size();
}
public void createAndStartUpdater() {
// check if there is previous instance of updater
@ -148,10 +172,19 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
}
public void stopUpdater() {
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)
&& handler != null && favsUpdater != null) {
handler.removeCallbacks(favsUpdater);
favsUpdater.setEnabled(false);
}
}
private class EmptyViewHolder extends RecyclerView.ViewHolder{
public EmptyViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}

Wyświetl plik

@ -0,0 +1,37 @@
package cc.pogoda.mobile.meteosystem.service;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import org.greenrobot.eventbus.EventBus;
import org.tinylog.Logger;
import java.util.List;
import cc.pogoda.mobile.meteosystem.dao.AllStationsDao;
import cc.pogoda.mobile.meteosystem.type.AllStationsReceivedEvent;
import cc.pogoda.mobile.meteosystem.type.StartStationsRefreshEvent;
import cc.pogoda.mobile.meteosystem.type.WeatherStation;
public class GetAllStationsService extends JobIntentService {
private static final String TAG = GetAllStationsService.class.getSimpleName();
private static final int JOB_ID = 1;
public static void enqueueWork(@NonNull Context context, @NonNull Intent intent) {
enqueueWork(context, GetAllStationsService.class, JOB_ID, intent);
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
EventBus.getDefault().post(new StartStationsRefreshEvent());
List<WeatherStation> allStations = new AllStationsDao().getAllStations();
if (allStations != null){
EventBus.getDefault().post(new AllStationsReceivedEvent(allStations));
Logger.debug(TAG + "onHandleWork done. allStations size:" + allStations.size());
}
}
}

Wyświetl plik

@ -0,0 +1,4 @@
package cc.pogoda.mobile.meteosystem.type;
public class StartStationsRefreshEvent {
}

Wyświetl plik

@ -0,0 +1,37 @@
<?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="match_parent">
<TextView
android:id="@+id/textViewEmpty1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:fontFamily="@font/alegreya_sans_sc_medium"
android:text="@string/all_stations_empty_list1"
android:textAlignment="center"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/textViewEmpty2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewEmpty2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/alegreya_sans_sc_medium"
android:text="@string/all_station_empty_list2"
android:textAlignment="center"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewEmpty1" />
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -1,10 +1,17 @@
<?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"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewFavourites"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/refreshViewFavourites"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewFavourites"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Wyświetl plik

@ -8,7 +8,4 @@
<item
android:id="@+id/fav_sort_add_order"
android:title="@string/sort_in_adding_order" />
<item
android:id="@+id/fav_remove_noext"
android:title="@string/clear_from_non_existent" />
</menu>

Wyświetl plik

@ -70,7 +70,7 @@
<string name="sort_in_adding_order">Sort in adding order</string>
<string name="clear_from_non_existent">Clear removed stations</string>
<string name="days_3">Three days</string>
<string name="plot_data_lenght">Plots data lenght</string>
<string name="plot_data_lenght">Plots data length</string>
<string name="pressure">Pressure</string>
<string name="wind">Wind</string>
<string name="current_value">Current Value</string>
@ -90,7 +90,7 @@
<string name="forecast">Weather forecast</string>
<string name="from">From</string>
<string name="to">To</string>
<string name="language">Laguage</string>
<string name="language">Language</string>
<string name="unit_of_measure">Unit of measure</string>
<string name="wind_unit_of_measure">Windspeed unit</string>
<string name="filter">Filter</string>
@ -114,4 +114,6 @@
<string name="export_decimation">Export data decimation</string>
<string name="export_decimation_minutes">Minimum time resolution</string>
<string name="www_link">URL to more information</string>
<string name="refreshing_station_list">Refreshing station list</string>
</resources>

Wyświetl plik

@ -114,4 +114,5 @@
<string name="export_decimation">Decymacja eskportowanych danych</string>
<string name="export_decimation_minutes">Minimalny krok w minutach</string>
<string name="www_link">Więcej informacji</string>
<string name="refreshing_station_list">Odświeżanie listy stacji</string>
</resources>

Wyświetl plik

@ -144,4 +144,7 @@
</string-array>
<string name="lang_change_req_restart" translatable="false">Changing language requires app restart after making a choose in this window.</string>
<string name="www_link">URL to more information</string>
<string name="refreshing_station_list">Refreshing station list</string>
<string name="all_stations_empty_list1">There are no stations on this list.</string>
<string name="all_station_empty_list2">Please wait or pull down to refresh list.</string>
</resources>