Changeset View
Changeset View
Standalone View
Standalone View
src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
Show All 15 Lines | BusTO - Fragments components | ||||
along with this program. If not, see <http://www.gnu.org/licenses/>. | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
package it.reyboz.bustorino.fragments; | package it.reyboz.bustorino.fragments; | ||||
import android.database.Cursor; | import android.database.Cursor; | ||||
import android.net.Uri; | import android.net.Uri; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.support.annotation.Nullable; | |||||
import android.support.v4.app.LoaderManager; | import androidx.annotation.Nullable; | ||||
import android.support.v4.content.CursorLoader; | import androidx.annotation.NonNull; | ||||
import android.support.v4.content.Loader; | import androidx.loader.app.LoaderManager; | ||||
import androidx.loader.content.CursorLoader; | |||||
import androidx.loader.content.Loader; | |||||
import android.util.Log; | import android.util.Log; | ||||
import android.view.LayoutInflater; | |||||
import android.view.View; | |||||
import android.view.ViewGroup; | |||||
import android.widget.ImageButton; | import android.widget.ImageButton; | ||||
import android.widget.ListAdapter; | |||||
import android.widget.ListView; | |||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import android.widget.Toast; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | |||||
import java.util.Collections; | |||||
import java.util.List; | |||||
import it.reyboz.bustorino.R; | import it.reyboz.bustorino.R; | ||||
import it.reyboz.bustorino.adapters.PalinaAdapter; | |||||
import it.reyboz.bustorino.backend.ArrivalsFetcher; | |||||
import it.reyboz.bustorino.backend.DBStatusManager; | import it.reyboz.bustorino.backend.DBStatusManager; | ||||
import it.reyboz.bustorino.backend.Fetcher; | |||||
import it.reyboz.bustorino.backend.FiveTAPIFetcher; | |||||
import it.reyboz.bustorino.backend.FiveTNormalizer; | |||||
import it.reyboz.bustorino.backend.FiveTScraperFetcher; | |||||
import it.reyboz.bustorino.backend.GTTJSONFetcher; | |||||
import it.reyboz.bustorino.backend.Palina; | |||||
import it.reyboz.bustorino.backend.Passaggio; | |||||
import it.reyboz.bustorino.backend.Route; | |||||
import it.reyboz.bustorino.middleware.AppDataProvider; | import it.reyboz.bustorino.middleware.AppDataProvider; | ||||
import it.reyboz.bustorino.middleware.NextGenDB; | import it.reyboz.bustorino.middleware.NextGenDB; | ||||
import it.reyboz.bustorino.middleware.UserDB; | import it.reyboz.bustorino.middleware.UserDB; | ||||
public class ArrivalsFragment extends ResultListFragment implements LoaderManager.LoaderCallbacks<Cursor> { | public class ArrivalsFragment extends ResultListFragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
private final static String KEY_STOP_ID = "stopid"; | private final static String KEY_STOP_ID = "stopid"; | ||||
private final static String KEY_STOP_NAME = "stopname"; | private final static String KEY_STOP_NAME = "stopname"; | ||||
private final static String DEBUG_TAG = "BUSTOArrivalsFragment"; | private final static String DEBUG_TAG = "BUSTOArrivalsFragment"; | ||||
private final static int loaderFavId = 2; | private final static int loaderFavId = 2; | ||||
private final static int loaderStopId = 1; | private final static int loaderStopId = 1; | ||||
private final static ArrivalsFetcher[] defaultFetchers = new ArrivalsFetcher[]{new FiveTAPIFetcher(), new GTTJSONFetcher(), new FiveTScraperFetcher()}; | |||||
static final String STOP_TITLE = "messageExtra"; | |||||
private @Nullable String stopID,stopName; | private @Nullable String stopID,stopName; | ||||
private TextView messageTextView; | |||||
private DBStatusManager prefs; | private DBStatusManager prefs; | ||||
private DBStatusManager.OnDBUpdateStatusChangeListener listener; | private DBStatusManager.OnDBUpdateStatusChangeListener listener; | ||||
private boolean justCreated = false; | private boolean justCreated = false; | ||||
private ImageButton addToFavorites; | private Palina lastUpdatedPalina = null; | ||||
private boolean needUpdateOnAttach = false; | |||||
private boolean requestedNewArrivalTimes = false; | |||||
//Views | |||||
protected ImageButton addToFavorites; | |||||
protected TextView timesSourceTextView; | |||||
private List<ArrivalsFetcher> fetchers = new ArrayList<>(Arrays.asList(defaultFetchers)); | |||||
public static ArrivalsFragment newInstance(String stopID){ | public static ArrivalsFragment newInstance(String stopID){ | ||||
return newInstance(stopID, null); | |||||
} | |||||
public static ArrivalsFragment newInstance(@NonNull String stopID, @Nullable String stopName){ | |||||
ArrivalsFragment fragment = new ArrivalsFragment(); | |||||
Bundle args = new Bundle(); | Bundle args = new Bundle(); | ||||
args.putString(KEY_STOP_ID,stopID); | args.putString(KEY_STOP_ID,stopID); | ||||
ArrivalsFragment fragment = new ArrivalsFragment(); | |||||
//parameter for ResultListFragment | //parameter for ResultListFragment | ||||
args.putSerializable(LIST_TYPE,FragmentKind.ARRIVALS); | args.putSerializable(LIST_TYPE,FragmentKind.ARRIVALS); | ||||
fragment.setArguments(args); | if (stopName != null){ | ||||
return fragment; | |||||
} | |||||
public static ArrivalsFragment newInstance(String stopID,String stopName){ | |||||
ArrivalsFragment fragment = newInstance(stopID); | |||||
Bundle args = fragment.getArguments(); | |||||
args.putString(KEY_STOP_NAME,stopName); | args.putString(KEY_STOP_NAME,stopName); | ||||
} | |||||
fragment.setArguments(args); | fragment.setArguments(args); | ||||
return fragment; | return fragment; | ||||
} | } | ||||
@Override | @Override | ||||
public void onCreate(Bundle savedInstanceState) { | public void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
stopID = getArguments().getString(KEY_STOP_ID); | stopID = getArguments().getString(KEY_STOP_ID); | ||||
//this might really be null | //this might really be null | ||||
stopName = getArguments().getString(KEY_STOP_NAME); | stopName = getArguments().getString(KEY_STOP_NAME); | ||||
final ArrivalsFragment f = this; | final ArrivalsFragment arrivalsFragment = this; | ||||
listener = new DBStatusManager.OnDBUpdateStatusChangeListener() { | listener = new DBStatusManager.OnDBUpdateStatusChangeListener() { | ||||
@Override | @Override | ||||
public void onDBStatusChanged(boolean updating) { | public void onDBStatusChanged(boolean updating) { | ||||
if(!updating){ | if(!updating){ | ||||
getLoaderManager().restartLoader(loaderFavId,getArguments(),f); | getLoaderManager().restartLoader(loaderFavId,getArguments(),arrivalsFragment); | ||||
} else { | } else { | ||||
final LoaderManager lm = getLoaderManager(); | final LoaderManager lm = getLoaderManager(); | ||||
lm.destroyLoader(loaderFavId); | lm.destroyLoader(loaderFavId); | ||||
lm.destroyLoader(loaderStopId); | lm.destroyLoader(loaderStopId); | ||||
} | } | ||||
} | } | ||||
@Override | @Override | ||||
public boolean defaultStatusValue() { | public boolean defaultStatusValue() { | ||||
return true; | return true; | ||||
} | } | ||||
}; | }; | ||||
prefs = new DBStatusManager(getContext().getApplicationContext(),listener); | prefs = new DBStatusManager(getContext().getApplicationContext(),listener); | ||||
justCreated = true; | justCreated = true; | ||||
} | } | ||||
@Override | @Override | ||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |||||
Bundle savedInstanceState) { | |||||
View root = inflater.inflate(R.layout.fragment_arrivals, container, false); | |||||
messageTextView = (TextView) root.findViewById(R.id.messageTextView); | |||||
addToFavorites = (ImageButton) root.findViewById(R.id.addToFavorites); | |||||
resultsListView = (ListView) root.findViewById(R.id.resultsListView); | |||||
timesSourceTextView = (TextView) root.findViewById(R.id.timesSourceTextView); | |||||
timesSourceTextView.setOnLongClickListener(view -> { | |||||
if(!requestedNewArrivalTimes){ | |||||
rotateFetchers(); | |||||
timesSourceTextView.setText(R.string.arrival_source_changing); | |||||
mListener.createFragmentForStop(stopID); | |||||
requestedNewArrivalTimes = true; | |||||
return true; | |||||
} | |||||
return false; | |||||
}); | |||||
timesSourceTextView.setOnClickListener(view -> { | |||||
Toast.makeText(getContext(), R.string.change_arrivals_source_message, Toast.LENGTH_SHORT) | |||||
.show(); | |||||
}); | |||||
//Button | |||||
addToFavorites.setClickable(true); | |||||
addToFavorites.setOnClickListener(v -> { | |||||
// add/remove the stop in the favorites | |||||
mListener.toggleLastStopToFavorites(); | |||||
}); | |||||
resultsListView.setOnItemClickListener((parent, view, position, id) -> { | |||||
String routeName; | |||||
Route r = (Route) parent.getItemAtPosition(position); | |||||
routeName = FiveTNormalizer.routeInternalToDisplay(r.getNameForDisplay()); | |||||
if (routeName == null) { | |||||
routeName = r.getNameForDisplay(); | |||||
} | |||||
if (r.destinazione == null || r.destinazione.length() == 0) { | |||||
Toast.makeText(getContext(), | |||||
getString(R.string.route_towards_unknown, routeName), Toast.LENGTH_SHORT).show(); | |||||
} else { | |||||
Toast.makeText(getContext(), | |||||
getString(R.string.route_towards_destination, routeName, r.destinazione), Toast.LENGTH_SHORT).show(); | |||||
} | |||||
}); | |||||
String displayName = getArguments().getString(STOP_TITLE); | |||||
setTextViewMessage(String.format( | |||||
getString(R.string.passages), displayName)); | |||||
String probablemessage = getArguments().getString(MESSAGE_TEXT_VIEW); | |||||
if (probablemessage != null) { | |||||
//Log.d("BusTO fragment " + this.getTag(), "We have a possible message here in the savedInstaceState: " + probablemessage); | |||||
messageTextView.setText(probablemessage); | |||||
messageTextView.setVisibility(View.VISIBLE); | |||||
} | |||||
return root; | |||||
} | |||||
@Override | |||||
public void onResume() { | public void onResume() { | ||||
super.onResume(); | super.onResume(); | ||||
LoaderManager loaderManager = getLoaderManager(); | LoaderManager loaderManager = getLoaderManager(); | ||||
if(stopID!=null){ | if(stopID!=null){ | ||||
//refresh the arrivals | //refresh the arrivals | ||||
if(!justCreated) | if(!justCreated) | ||||
mListener.createFragmentForStop(stopID); | mListener.createFragmentForStop(stopID); | ||||
else justCreated = false; | else justCreated = false; | ||||
//start the loader | //start the loader | ||||
if(prefs.isDBUpdating(true)){ | if(prefs.isDBUpdating(true)){ | ||||
prefs.registerListener(); | prefs.registerListener(); | ||||
} else { | } else { | ||||
loaderManager.restartLoader(loaderFavId, getArguments(), this); | loaderManager.restartLoader(loaderFavId, getArguments(), this); | ||||
} | } | ||||
updateMessage(); | updateMessage(); | ||||
} | } | ||||
} | } | ||||
@Override | |||||
public void onStart() { | |||||
super.onStart(); | |||||
if (needUpdateOnAttach){ | |||||
updateFragmentData(null); | |||||
} | |||||
} | |||||
@Nullable | @Nullable | ||||
public String getStopID() { | public String getStopID() { | ||||
return stopID; | return stopID; | ||||
} | } | ||||
/** | /** | ||||
* Give the fetchers | |||||
* @return the list of the fetchers | |||||
*/ | |||||
public ArrayList<Fetcher> getCurrentFetchers(){ | |||||
ArrayList<Fetcher> v = new ArrayList<Fetcher>(); | |||||
for (ArrivalsFetcher fetcher: fetchers){ | |||||
v.add(fetcher); | |||||
} | |||||
return v; | |||||
} | |||||
public Fetcher[] getCurrentFetchersAsArray(){ | |||||
Fetcher[] arr = new Fetcher[fetchers.size()]; | |||||
fetchers.toArray(arr); | |||||
return arr; | |||||
} | |||||
private void rotateFetchers(){ | |||||
Collections.rotate(fetchers, -1); | |||||
} | |||||
/** | |||||
* Update the UI with the new data | |||||
* @param p the full Palina | |||||
*/ | |||||
public void updateFragmentData(@Nullable Palina p){ | |||||
if (p!=null) | |||||
lastUpdatedPalina = p; | |||||
if (!isAdded()){ | |||||
//defer update at next show | |||||
if (p==null) | |||||
Log.w(DEBUG_TAG, "Asked to update the data, but we're not attached and the data is null"); | |||||
else needUpdateOnAttach = true; | |||||
} else { | |||||
final PalinaAdapter adapter = new PalinaAdapter(getContext(), lastUpdatedPalina); | |||||
showArrivalsSources(lastUpdatedPalina); | |||||
super.resetListAdapter(adapter); | |||||
} | |||||
} | |||||
/** | |||||
* Set the message of the arrival times source | |||||
* @param p Palina with the arrival times | |||||
*/ | |||||
protected void showArrivalsSources(Palina p){ | |||||
final Passaggio.Source source = p.getPassaggiSourceIfAny(); | |||||
String source_txt; | |||||
switch (source){ | |||||
case GTTJSON: | |||||
source_txt = getString(R.string.gttjsonfetcher); | |||||
break; | |||||
case FiveTAPI: | |||||
source_txt = getString(R.string.fivetapifetcher); | |||||
break; | |||||
case FiveTScraper: | |||||
source_txt = getString(R.string.fivetscraper); | |||||
break; | |||||
case UNDETERMINED: | |||||
//Don't show the view | |||||
timesSourceTextView.setVisibility(View.GONE); | |||||
return; | |||||
default: | |||||
throw new IllegalStateException("Unexpected value: " + source); | |||||
} | |||||
final String base_message = getString(R.string.times_source_fmt, source_txt); | |||||
timesSourceTextView.setVisibility(View.VISIBLE); | |||||
timesSourceTextView.setText(base_message); | |||||
requestedNewArrivalTimes = false; | |||||
} | |||||
@Override | |||||
public void setNewListAdapter(ListAdapter adapter) { | |||||
throw new UnsupportedOperationException(); | |||||
} | |||||
/** | |||||
* Update the message in the fragment | * Update the message in the fragment | ||||
* | * | ||||
* It may eventually change the "Add to Favorite" icon | * It may eventually change the "Add to Favorite" icon | ||||
*/ | */ | ||||
private void updateMessage(){ | private void updateMessage(){ | ||||
String message = null; | String message = null; | ||||
if (stopName != null && stopID != null && stopName.length() > 0) { | if (stopName != null && stopID != null && stopName.length() > 0) { | ||||
message = (stopID.concat(" - ").concat(stopName)); | message = (stopID.concat(" - ").concat(stopName)); | ||||
▲ Show 20 Lines • Show All 83 Lines • Show Last 20 Lines |
Public contents are in Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) or GNU Free Documentation License (at your option) unless otherwise noted. · Contact / Register