Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F2444105
D119.1729696636.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
44 KB
Referenced Files
None
Subscribers
None
D119.1729696636.diff
View Options
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/AdapterClickListener.java b/app/src/main/java/it/reyboz/bustorino/adapters/AdapterClickListener.java
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/AdapterClickListener.java
@@ -0,0 +1,6 @@
+package it.reyboz.bustorino.adapters;
+
+public interface AdapterClickListener<T> {
+
+ void onAdapterClickListener(T element);
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java b/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
--- a/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
@@ -27,14 +27,11 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
import android.widget.TextView;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
+import java.util.*;
+import androidx.recyclerview.widget.RecyclerView;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.Palina;
import it.reyboz.bustorino.backend.Passaggio;
@@ -42,6 +39,7 @@
import it.reyboz.bustorino.backend.utils;
import it.reyboz.bustorino.util.PassaggiSorter;
import it.reyboz.bustorino.util.RouteSorterByArrivalTime;
+import org.jetbrains.annotations.NotNull;
/**
* This once was a ListView Adapter for BusLine[].
@@ -52,9 +50,9 @@
* @author Valerio Bozzolan
* @author Ludovico Pavesi
*/
-public class PalinaAdapter extends ArrayAdapter<Route> implements SharedPreferences.OnSharedPreferenceChangeListener {
- private LayoutInflater li;
- private static int row_layout = R.layout.entry_bus_line_passage;
+public class PalinaAdapter extends RecyclerView.Adapter<PalinaAdapter.PalinaViewHolder> implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private static final int ROW_LAYOUT = R.layout.entry_bus_line_passage;
private static final int metroBg = R.drawable.route_background_metro;
private static final int busBg = R.drawable.route_background_bus;
private static final int extraurbanoBg = R.drawable.route_background_bus_long_distance;
@@ -65,98 +63,22 @@
private final String KEY_CAPITALIZE;
private Capitalize capit;
- //private static final int cityIcon = R.drawable.city;
-
- // hey look, a pattern!
- private static class ViewHolder {
- TextView rowStopIcon;
- TextView rowRouteDestination;
- TextView rowRouteTimetable;
- }
- private static Capitalize getCapitalize(SharedPreferences shPr, String key){
- String capitalize = shPr.getString(key, "");
-
- switch (capitalize.trim()){
- case "KEEP":
- return Capitalize.DO_NOTHING;
- case "CAPITALIZE_ALL":
- return Capitalize.ALL;
-
- case "CAPITALIZE_FIRST":
- return Capitalize.FIRST;
- }
- return Capitalize.DO_NOTHING;
- }
-
- public PalinaAdapter(Context context, Palina p) {
- super(context, row_layout, p.queryAllRoutes());
- li = LayoutInflater.from(context);
- Comparator<Passaggio> sorter = null;
- if (p.getPassaggiSourceIfAny()== Passaggio.Source.GTTJSON){
- sorter = new PassaggiSorter();
- }
- for(Route r: p.queryAllRoutes()){
- if (sorter==null) Collections.sort(r.passaggi);
- else Collections.sort(r.passaggi, sorter);
- }
- sort(new RouteSorterByArrivalTime());
- /*
- sort(new Comparator<Route>() {
-
- @Override
- public int compare(Route route, Route t1) {
- LinesNameSorter sorter = new LinesNameSorter();
- if(route.getNameForDisplay()!= null){
- if(t1.getNameForDisplay()!=null){
- return sorter.compare(route.getNameForDisplay(), t1.getNameForDisplay());
- }
- else return -1;
- } else if(t1.getNameForDisplay()!=null){
- return +1;
- }
- else return 0;
- }
- });
-
- */
- KEY_CAPITALIZE = context.getString(R.string.pref_arrival_times_capit);
- SharedPreferences defSharPref = PreferenceManager.getDefaultSharedPreferences(context);
- defSharPref.registerOnSharedPreferenceChangeListener(this);
- this.capit = getCapitalize(defSharPref, KEY_CAPITALIZE);
- }
+ private final List<Route> mRoutes;
+ private final AdapterClickListener<Route> mRouteListener;
- /**
- * Some parts taken from the AdapterBusLines class.<br>
- * Some parts inspired by these enlightening tutorials:<br>
- * http://www.simplesoft.it/android/guida-agli-adapter-e-le-listview-in-android.html<br>
- * https://www.codeofaninja.com/2013/09/android-viewholder-pattern-example.html<br>
- * And some other bits and bobs TIRATI FUORI DAL NULLA CON L'INTUIZIONE INTELLETTUALE PERCHÉ
- * SEMBRA CHE NESSUNO ABBIA LA MINIMA IDEA DI COME FUNZIONA UN ADAPTER SU ANDROID.
- */
@NonNull
+ @NotNull
@Override
- public View getView(int position, View convertView, @NonNull ViewGroup parent) {
- ViewHolder vh;
-
- if(convertView == null) {
- // INFLATE!
- // setting a parent here is not supported and causes a fatal exception, apparently.
- convertView = li.inflate(row_layout, null);
-
- // STORE TEXTVIEWS!
- vh = new ViewHolder();
- vh.rowStopIcon = (TextView) convertView.findViewById(R.id.routeID);
- vh.rowRouteDestination = (TextView) convertView.findViewById(R.id.routeDestination);
- vh.rowRouteTimetable = (TextView) convertView.findViewById(R.id.routesThatStopHere);
+ public PalinaViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(ROW_LAYOUT, parent, false);
+ return new PalinaViewHolder(view);
+ }
- // STORE VIEWHOLDER IN\ON\OVER\UNDER\ABOVE\BESIDE THE VIEW!
- convertView.setTag(vh);
- } else {
- // RECOVER THIS STUFF!
- vh = (ViewHolder) convertView.getTag();
- }
+ @Override
+ public void onBindViewHolder(@NonNull @NotNull PalinaViewHolder vh, int position) {
+ final Route route = mRoutes.get(position);
- Route route = getItem(position);
vh.rowStopIcon.setText(route.getNameForDisplay());
if(route.destinazione==null || route.destinazione.length() == 0) {
vh.rowRouteDestination.setVisibility(View.GONE);
@@ -184,6 +106,11 @@
}
vh.rowRouteDestination.setText(dest);
+
+ //set click listener
+ vh.itemView.setOnClickListener(view -> {
+ mRouteListener.onAdapterClickListener(route);
+ });
}
switch (route.type) {
@@ -223,9 +150,82 @@
vh.rowRouteTimetable.setText(route.getPassaggiToString());
}
- return convertView;
}
+ @Override
+ public int getItemCount() {
+ return mRoutes.size();
+ }
+
+ //private static final int cityIcon = R.drawable.city;
+
+ // hey look, a pattern!
+ public static class PalinaViewHolder extends RecyclerView.ViewHolder {
+ final TextView rowStopIcon;
+ final TextView rowRouteDestination;
+ final TextView rowRouteTimetable;
+
+ public PalinaViewHolder(@NonNull @NotNull View view) {
+ super(view);
+ /*
+ convertView.findViewById(R.id.routeID);
+ vh.rowRouteDestination = (TextView) convertView.findViewById(R.id.routeDestination);
+ vh.rowRouteTimetable = (TextView) convertView.findViewById(R.id.routesThatStopHere);
+ */
+ rowStopIcon = view.findViewById(R.id.routeID);
+ rowRouteDestination = view.findViewById(R.id.routeDestination);
+ rowRouteTimetable = view.findViewById(R.id.routesThatStopHere);
+ }
+ }
+ private static Capitalize getCapitalize(SharedPreferences shPr, String key){
+ String capitalize = shPr.getString(key, "");
+
+ switch (capitalize.trim()){
+ case "KEEP":
+ return Capitalize.DO_NOTHING;
+ case "CAPITALIZE_ALL":
+ return Capitalize.ALL;
+
+ case "CAPITALIZE_FIRST":
+ return Capitalize.FIRST;
+ }
+ return Capitalize.DO_NOTHING;
+ }
+
+ public PalinaAdapter(Context context, Palina p, AdapterClickListener<Route> listener, boolean hideEmptyRoutes) {
+ Comparator<Passaggio> sorter = null;
+ if (p.getPassaggiSourceIfAny()== Passaggio.Source.GTTJSON){
+ sorter = new PassaggiSorter();
+ }
+ final List<Route> routes;
+ if (hideEmptyRoutes){
+ // build the routes by filtering them
+ routes = new ArrayList<>();
+ for(Route r: p.queryAllRoutes()){
+ //add only if there is at least one passage
+ if (r.numPassaggi()>0){
+ routes.add(r);
+ }
+ }
+ } else
+ routes = p.queryAllRoutes();
+ for(Route r: routes){
+ if (sorter==null) Collections.sort(r.passaggi);
+ else Collections.sort(r.passaggi, sorter);
+ }
+
+ Collections.sort(routes,new RouteSorterByArrivalTime());
+
+ mRoutes = routes;
+ KEY_CAPITALIZE = context.getString(R.string.pref_arrival_times_capit);
+ SharedPreferences defSharPref = PreferenceManager.getDefaultSharedPreferences(context);
+ defSharPref.registerOnSharedPreferenceChangeListener(this);
+ this.capit = getCapitalize(defSharPref, KEY_CAPITALIZE);
+
+ this.mRouteListener = listener;
+ }
+
+
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt b/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
@@ -0,0 +1,48 @@
+package it.reyboz.bustorino.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import it.reyboz.bustorino.R
+import it.reyboz.bustorino.backend.Palina
+
+class RouteOnlyLineAdapter (val routeNames: List<String>) :
+ RecyclerView.Adapter<RouteOnlyLineAdapter.ViewHolder>() {
+
+ /**
+ * Provide a reference to the type of views that you are using
+ * (custom ViewHolder)
+ */
+ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val textView: TextView
+
+ init {
+ // Define click listener for the ViewHolder's View
+ textView = view.findViewById(R.id.routeBallID)
+ }
+ }
+ constructor(palina: Palina, showOnlyEmpty: Boolean): this(palina.routesNamesWithNoPassages)
+
+ // Create new views (invoked by the layout manager)
+ override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
+ // Create a new view, which defines the UI of the list item
+ val view = LayoutInflater.from(viewGroup.context)
+ .inflate(R.layout.round_line_header, viewGroup, false)
+
+ return ViewHolder(view)
+ }
+
+ // Replace the contents of a view (invoked by the layout manager)
+ override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
+
+ // Get element from your dataset at this position and replace the
+ // contents of the view with that element
+ viewHolder.textView.text = routeNames[position]
+ }
+
+ // Return the size of your dataset (invoked by the layout manager)
+ override fun getItemCount() = routeNames.size
+
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/Palina.java b/app/src/main/java/it/reyboz/bustorino/backend/Palina.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/Palina.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/Palina.java
@@ -400,5 +400,18 @@
if (min == Integer.MAX_VALUE) return 0;
else return min;
}
+
+ public ArrayList<String> getRoutesNamesWithNoPassages(){
+ ArrayList<String> mList = new ArrayList<>();
+ if(routes==null || routes.size() == 0){
+ return mList;
+ }
+ for(Route r: routes){
+ if(r.numPassaggi()==0)
+ mList.add(r.getNameForDisplay());
+ }
+
+ return mList;
+ }
//private void mergeRoute
}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.java
@@ -18,13 +18,16 @@
package it.reyboz.bustorino.fragments;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+import android.widget.*;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
+import androidx.core.widget.NestedScrollView;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
@@ -33,17 +36,19 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageButton;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import it.reyboz.bustorino.R;
+import it.reyboz.bustorino.adapters.AdapterClickListener;
import it.reyboz.bustorino.adapters.PalinaAdapter;
+import it.reyboz.bustorino.adapters.RouteOnlyLineAdapter;
import it.reyboz.bustorino.backend.ArrivalsFetcher;
import it.reyboz.bustorino.backend.DBStatusManager;
import it.reyboz.bustorino.backend.Fetcher;
@@ -57,8 +62,10 @@
import it.reyboz.bustorino.data.NextGenDB;
import it.reyboz.bustorino.data.UserDB;
import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction;
+import it.reyboz.bustorino.util.LinesNameSorter;
+import it.reyboz.bustorino.util.ViewUtils;
-public class ArrivalsFragment extends ResultListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
+public class ArrivalsFragment extends ResultBaseFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private final static String KEY_STOP_ID = "stopid";
private final static String KEY_STOP_NAME = "stopname";
@@ -81,11 +88,41 @@
//Views
protected ImageButton addToFavorites;
protected TextView timesSourceTextView;
+ protected TextView messageTextView;
+ protected RecyclerView arrivalsRecyclerView;
+ private PalinaAdapter mListAdapter = null;
+
+ //private NestedScrollView theScrollView;
+ protected RecyclerView noArrivalsRecyclerView;
+ private RouteOnlyLineAdapter noArrivalsAdapter;
+ private TextView noArrivalsTitleView;
+ private GridLayoutManager layoutManager;
+
+ //private View canaryEndView;
private List<ArrivalsFetcher> fetchers = null; //new ArrayList<>(Arrays.asList(utils.getDefaultArrivalsFetchers()));
private boolean reloadOnResume = true;
+ private final AdapterClickListener<Route> mRouteClickListener = route -> {
+ String routeName;
+
+ routeName = FiveTNormalizer.routeInternalToDisplay(route.getNameForDisplay());
+ if (routeName == null) {
+ routeName = route.getNameForDisplay();
+ }
+ if(getContext()==null)
+ Log.e(DEBUG_TAG, "Touched on a route but Context is null");
+ else if (route.destinazione == null || route.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, route.destinazione), Toast.LENGTH_SHORT).show();
+ }
+
+ };
+
public static ArrivalsFragment newInstance(String stopID){
return newInstance(stopID, null);
}
@@ -95,7 +132,7 @@
Bundle args = new Bundle();
args.putString(KEY_STOP_ID,stopID);
//parameter for ResultListFragmentrequestArrivalsForStopID
- args.putSerializable(LIST_TYPE,FragmentKind.ARRIVALS);
+ //args.putSerializable(LIST_TYPE,FragmentKind.ARRIVALS);
if (stopName != null){
args.putString(KEY_STOP_NAME,stopName);
}
@@ -103,6 +140,10 @@
return fragment;
}
+ public static String getFragmentTag(Palina p) {
+ return "palina_"+p.ID;
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -140,7 +181,14 @@
View root = inflater.inflate(R.layout.fragment_arrivals, container, false);
messageTextView = root.findViewById(R.id.messageTextView);
addToFavorites = root.findViewById(R.id.addToFavorites);
- resultsListView = root.findViewById(R.id.resultsListView);
+ //theScrollView = root.findViewById(R.id.arrivalsScrollView);
+ // recyclerview holding the arrival times
+ arrivalsRecyclerView = root.findViewById(R.id.arrivalsRecyclerView);
+ final LinearLayoutManager manager = new LinearLayoutManager(getContext());
+ arrivalsRecyclerView.setLayoutManager(manager);
+ final DividerItemDecoration mDividerItemDecoration = new DividerItemDecoration(arrivalsRecyclerView.getContext(),
+ manager.getOrientation());
+ arrivalsRecyclerView.addItemDecoration(mDividerItemDecoration);
timesSourceTextView = root.findViewById(R.id.timesSourceTextView);
timesSourceTextView.setOnLongClickListener(view -> {
if(!fetchersChangeRequestPending){
@@ -165,25 +213,9 @@
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);
if(displayName!=null)
- setTextViewMessage(String.format(
+ setTextViewMessage(String.format(
getString(R.string.passages), displayName));
@@ -193,6 +225,19 @@
messageTextView.setText(probablemessage);
messageTextView.setVisibility(View.VISIBLE);
}
+ //no arrivals stuff
+ noArrivalsRecyclerView = root.findViewById(R.id.noArrivalsRecyclerView);
+ layoutManager = new GridLayoutManager(getContext(),60);
+ layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+ @Override
+ public int getSpanSize(int position) {
+ return 12;
+ }
+ });
+ noArrivalsRecyclerView.setLayoutManager(layoutManager);
+ noArrivalsTitleView = root.findViewById(R.id.noArrivalsMessageTextView);
+
+ //canaryEndView = root.findViewById(R.id.canaryEndView);
/*String sourcesTextViewData = getArguments().getString(SOURCES_TEXT);
if (sourcesTextViewData!=null){
@@ -208,13 +253,23 @@
public void onResume() {
super.onResume();
LoaderManager loaderManager = getLoaderManager();
- Log.d(DEBUG_TAG, "OnResume, justCreated "+justCreated);
+ Log.d(DEBUG_TAG, "OnResume, justCreated "+justCreated+", lastUpdatedPalina is: "+lastUpdatedPalina);
/*if(needUpdateOnAttach){
updateFragmentData(null);
needUpdateOnAttach=false;
}*/
+ /*if(lastUpdatedPalina!=null){
+ updateFragmentData(null);
+ showArrivalsSources(lastUpdatedPalina);
+ }*/
+ if (mListAdapter!=null)
+ resetListAdapter(mListAdapter);
+ if(noArrivalsAdapter!=null){
+ noArrivalsRecyclerView.setAdapter(noArrivalsAdapter);
+
+ }
+
if(stopID!=null){
- //refresh the arrivals
if(!justCreated){
fetchers = utils.getDefaultArrivalsFetchers(getContext());
adjustFetchersToSource();
@@ -314,12 +369,35 @@
else needUpdateOnAttach = true;
} else {
- final PalinaAdapter adapter = new PalinaAdapter(getContext(), lastUpdatedPalina);
+ final PalinaAdapter adapter = new PalinaAdapter(getContext(), lastUpdatedPalina, mRouteClickListener, true);
showArrivalsSources(lastUpdatedPalina);
- super.resetListAdapter(adapter);
+ resetListAdapter(adapter);
+
+ final ArrayList<String> routesWithNoPassages = lastUpdatedPalina.getRoutesNamesWithNoPassages();
+ Collections.sort(routesWithNoPassages, new LinesNameSorter());
+ noArrivalsAdapter = new RouteOnlyLineAdapter(routesWithNoPassages);
+ if(noArrivalsRecyclerView!=null){
+ noArrivalsRecyclerView.setAdapter(noArrivalsAdapter);
+ //hide the views if there are no empty routes
+ if(routesWithNoPassages.isEmpty()){
+ noArrivalsRecyclerView.setVisibility(View.GONE);
+ noArrivalsTitleView.setVisibility(View.GONE);
+ } else {
+ noArrivalsRecyclerView.setVisibility(View.VISIBLE);
+ noArrivalsTitleView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ //canaryEndView.setVisibility(View.VISIBLE);
+ //check if canaryEndView is visible
+ //boolean isCanaryVisibile = ViewUtils.Companion.isViewPartiallyVisibleInScroll(canaryEndView, theScrollView);
+ //Log.d(DEBUG_TAG, "Canary view fully visibile: "+isCanaryVisibile);
+
}
}
+
+
/**
* Set the message of the arrival times source
* @param p Palina with the arrival times
@@ -357,6 +435,8 @@
Log.w(DEBUG_TAG, "Tried to update the source fetcher but it didn't work");
final String base_message = getString(R.string.times_source_fmt, source_txt);
timesSourceTextView.setText(base_message);
+ timesSourceTextView.setVisibility(View.VISIBLE);
+
if (p.getTotalNumberOfPassages() > 0) {
timesSourceTextView.setVisibility(View.VISIBLE);
} else {
@@ -383,11 +463,6 @@
return adjustFetchersToSource(source);
}
- @Override
- public void setNewListAdapter(ListAdapter adapter) {
- throw new UnsupportedOperationException();
- }
-
/**
* Update the message in the fragment
*
@@ -484,7 +559,22 @@
public void onLoaderReset(Loader<Cursor> loader) {
//NOTHING TO DO
}
+ protected void resetListAdapter(PalinaAdapter adapter) {
+ mListAdapter = adapter;
+ if (arrivalsRecyclerView != null) {
+ arrivalsRecyclerView.setAdapter(adapter);
+ arrivalsRecyclerView.setVisibility(View.VISIBLE);
+ }
+ }
+ /**
+ * Set the message textView
+ * @param message the whole message to write in the textView
+ */
+ public void setTextViewMessage(String message) {
+ messageTextView.setText(message);
+ messageTextView.setVisibility(View.VISIBLE);
+ }
public void toggleLastStopToFavorites() {
@@ -553,7 +643,17 @@
@Override
public void onDestroyView() {
- getArguments().putString(SOURCES_TEXT, timesSourceTextView.getText().toString());
+ arrivalsRecyclerView = null;
+ if(getArguments()!=null) {
+ getArguments().putString(SOURCES_TEXT, timesSourceTextView.getText().toString());
+ getArguments().putString(MESSAGE_TEXT_VIEW, messageTextView.getText().toString());
+ }
super.onDestroyView();
}
+
+ public boolean isFragmentForTheSameStop(Palina p) {
+ if (getTag() != null)
+ return getTag().equals(getFragmentTag(p));
+ else return false;
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/FragmentHelper.java b/app/src/main/java/it/reyboz/bustorino/fragments/FragmentHelper.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/FragmentHelper.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/FragmentHelper.java
@@ -126,7 +126,7 @@
} else {
arrivalsFragment = ArrivalsFragment.newInstance(p.ID);
}
- String probableTag = ResultListFragment.getFragmentTag(p);
+ String probableTag = ArrivalsFragment.getFragmentTag(p);
attachFragmentToContainer(fm,arrivalsFragment,new AttachParameters(probableTag, true, addToBackStack));
}
// DO NOT CALL `setListAdapter` ever on arrivals fragment
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
@@ -137,7 +137,7 @@
uri = Uri.parse(result.getContents()); // this apparently prevents NullPointerException. Somehow.
} catch (NullPointerException e) {
if (getContext()!=null)
- Toast.makeText(getContext().getApplicationContext(),
+ Toast.makeText(getContext().getApplicationContext(),
R.string.no_qrcode, Toast.LENGTH_SHORT).show();
return;
}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ResultBaseFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ResultBaseFragment.java
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ResultBaseFragment.java
@@ -0,0 +1,33 @@
+package it.reyboz.bustorino.fragments;
+
+import android.content.Context;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+
+public abstract class ResultBaseFragment extends Fragment {
+
+ protected FragmentListenerMain mListener;
+ protected static final String MESSAGE_TEXT_VIEW = "message_text_view";
+
+
+ public ResultBaseFragment() {
+ }
+ @Override
+ public void onAttach(@NonNull Context context) {
+ super.onAttach(context);
+ if (context instanceof FragmentListenerMain) {
+ mListener = (FragmentListenerMain) context;
+ } else {
+ throw new RuntimeException(context.toString()
+ + " must implement FragmentListenerMain");
+ }
+
+ }
+
+ @Override
+ public void onDetach() {
+ mListener.showFloatingActionButton(false);
+ mListener = null;
+ super.onDetach();
+ }
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java
@@ -285,9 +285,6 @@
resultsListView.setVisibility(View.VISIBLE);
}
}
- public void setNewListAdapter(ListAdapter adapter){
- resetListAdapter(adapter);
- }
/**
* Set the message textView
diff --git a/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt b/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/util/ViewUtils.kt
@@ -0,0 +1,33 @@
+package it.reyboz.bustorino.util
+
+import android.graphics.Rect
+import android.util.Log
+
+import android.view.View
+import androidx.core.widget.NestedScrollView
+
+
+class ViewUtils {
+
+ companion object{
+ const val DEBUG_TAG="BusTO:ViewUtils"
+ fun isViewFullyVisibleInScroll(view: View, scrollView: NestedScrollView): Boolean {
+ val scrollBounds = Rect()
+ scrollView.getDrawingRect(scrollBounds)
+ val top = view.y
+ val bottom = top + view.height
+ Log.d(DEBUG_TAG, "Scroll bounds are $scrollBounds, top:${view.y}, bottom $bottom")
+ return (scrollBounds.top < top && scrollBounds.bottom > bottom)
+ }
+ fun isViewPartiallyVisibleInScroll(view: View, scrollView: NestedScrollView): Boolean{
+ val scrollBounds = Rect()
+ scrollView.getHitRect(scrollBounds)
+ Log.d(DEBUG_TAG, "Scroll bounds are $scrollBounds")
+ if (view.getLocalVisibleRect(scrollBounds)) {
+ return true
+ } else {
+ return false
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/entry_bus_line_passage.xml b/app/src/main/res/layout/entry_bus_line_passage.xml
--- a/app/src/main/res/layout/entry_bus_line_passage.xml
+++ b/app/src/main/res/layout/entry_bus_line_passage.xml
@@ -7,6 +7,7 @@
android:paddingLeft="16dip"
android:paddingRight="16dip">
+
<TextView
android:id="@+id/routeID"
android:layout_width="54dip"
diff --git a/app/src/main/res/layout/fragment_arrivals.xml b/app/src/main/res/layout/fragment_arrivals.xml
--- a/app/src/main/res/layout/fragment_arrivals.xml
+++ b/app/src/main/res/layout/fragment_arrivals.xml
@@ -1,98 +1,147 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:fab="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+<RelativeLayout
+ 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"
+ android:orientation="vertical"
+ android:paddingTop="8dp">
<androidx.cardview.widget.CardView
- android:id="@+id/messageCardView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginLeft="16dp"
- android:layout_marginTop="16dp"
- android:layout_marginEnd="16dp"
- android:layout_marginRight="16dp"
- android:layout_marginBottom="10dp"
- fab:cardCornerRadius="5dp"
- fab:cardElevation="2dp">
+ android:id="@+id/messageCardView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="5dp"
+ app:cardElevation="2dp"
+ >
<TextView
- android:id="@+id/messageTextView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginLeft="8dp"
- android:layout_toStartOf="@+id/addToFavorites"
- android:layout_toLeftOf="@+id/addToFavorites"
-
- android:foreground="?attr/selectableItemBackground"
- android:gravity="center_vertical"
- android:minHeight="40dp"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:id="@+id/messageTextView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_toStartOf="@+id/addToFavorites"
+ android:layout_toLeftOf="@+id/addToFavorites"
+
+ android:foreground="?attr/selectableItemBackground"
+ android:gravity="center_vertical"
+ android:minHeight="40dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
<ImageButton
- android:id="@+id/addToFavorites"
- android:layout_width="45dp"
- android:layout_height="match_parent"
- android:layout_gravity="end"
- android:background="@android:color/transparent"
- android:foreground="?attr/selectableItemBackground"
- fab:srcCompat="@drawable/ic_star_outline"
- tools:ignore="OnClick" />
+ android:id="@+id/addToFavorites"
+ android:layout_width="45dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="end"
+ android:background="@android:color/transparent"
+ android:foreground="?attr/selectableItemBackground"
+ app:srcCompat="@drawable/ic_star_outline"
+ tools:ignore="OnClick"/>
</androidx.cardview.widget.CardView>
-
<LinearLayout
- android:layout_width="match_parent"
- android:layout_below="@+id/messageCardView"
- android:orientation="vertical"
-
- android:layout_height="wrap_content">
-
- <ListView
- android:id="@+id/resultsListView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="9"
- android:clickable="true"
- android:descendantFocusability="blocksDescendants"
- android:focusable="true"
- android:scrollbars="vertical"
- android:visibility="visible">
-
- </ListView>
-
- <View
- android:id="@+id/divider_arr"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="@color/grey_100"
- />
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/messageCardView"
+ android:orientation="vertical">
+
+ <androidx.core.widget.NestedScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/arrivalsScrollView"
+ android:layout_weight="12"
+ >
<LinearLayout
- android:id="@+id/theLinearLayout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_width="match_parent" android:layout_height="wrap_content">
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/arrivalsRecyclerView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:descendantFocusability="blocksDescendants"
+ android:focusable="true"
+
+ android:visibility="visible"
+ android:nestedScrollingEnabled="false"
+
+ android:layout_marginTop="8dp"/>
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/no_passages_title"
+ android:textAppearance="@style/TextAppearance.AppCompat.Display1"
+ android:textSize="22sp"
+ android:id="@+id/noArrivalsMessageTextView"
+ android:minHeight="0dp"
+ android:layout_marginLeft="12dp"
+ android:layout_marginStart="12dp"
+ android:layout_marginEnd="12dp"
+ android:layout_marginRight="12dp"
+
+ />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/noArrivalsRecyclerView"
+ android:nestedScrollingEnabled="false"
+ android:layout_marginLeft="@dimen/margin_arr"
+ android:layout_marginStart="@dimen/margin_arr"
+ android:layout_marginEnd="@dimen/margin_arr"
+ android:layout_marginRight="@dimen/margin_arr"
+
+ />
+ <!--
+ <View
+ android:id="@+id/canaryEndView"
+ android:layout_height="2dp"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="@dimen/margin_arr"
+ android:layout_marginStart="@dimen/margin_arr"
+ android:layout_marginEnd="@dimen/margin_arr"
+ android:layout_marginRight="@dimen/margin_arr"
+ android:background="@color/orange_500"
+ />
+ -->
- android:layout_marginTop="5dp"
+ </LinearLayout>
+
+ </androidx.core.widget.NestedScrollView>
+
+
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:id="@+id/bottomLinearLayout"
+ android:gravity="top"
+ >
+ <View
+ android:id="@+id/divider_arr"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@color/grey_200"
+
+ />
- android:layout_marginBottom="5dp"
- android:orientation="horizontal">
<TextView
- android:id="@+id/timesSourceTextView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="15dp"
- android:layout_marginLeft="15dp"
- android:text=""
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="19sp"
-
- />
- </LinearLayout>
+ android:id="@+id/timesSourceTextView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="20sp"
+
+ android:gravity="center_vertical"
+ android:paddingBottom="5dp"
+ android:layout_marginStart="10dp"
+ android:layout_marginTop="5dp"
+ />
+ </LinearLayout>
</LinearLayout>
-
</RelativeLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/round_line_header.xml b/app/src/main/res/layout/round_line_header.xml
new file mode 100644
--- /dev/null
+++ b/app/src/main/res/layout/round_line_header.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+
+ android:background="@color/orange_500"
+ app:cardCornerRadius="54sp"
+ app:cardElevation="0sp"
+ android:layout_gravity="center_vertical"
+ android:layout_margin="5dp"
+ android:padding="3dp"
+ app:cardBackgroundColor="@color/orange_500"
+>
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:minHeight="54sp"
+ android:minWidth="54sp"
+ >
+ <TextView
+ android:id="@+id/routeBallID"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="@color/grey_100"
+ android:textSize="21sp"
+ android:text="231"
+ android:paddingStart="4sp"
+ android:paddingLeft="4sp"
+ android:paddingRight="4sp"
+ android:paddingEnd="4sp"
+ >
+ </TextView>
+ </RelativeLayout>
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -155,6 +155,8 @@
<string name="arrival_source_changing">Cambiamento sorgente orari…</string>
<string name="change_arrivals_source_message">Premi a lungo per cambiare la sorgente degli orari</string>
+ <string name="no_passages_title">Nessun passaggio per le linee:</string>
+
<string name="default_notification_channel_description">Canale unico delle notifiche</string>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -18,6 +18,7 @@
<color name="teal_300">#4DB6AC</color>
<color name="teal_200">#80cbc4</color>
<color name="grey_100">#F5F5F5</color>
+ <color name="grey_200">#dddddd</color>
<color name="grey_050">#f8f8f8</color>
<color name="grey_600">#757575</color>
<!--<color name="white">#FFFFFF</color>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -9,4 +9,6 @@
<dimen name="default_textView_margin">6dp</dimen>
+ <dimen name="margin_arr">5dp</dimen>
+
</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -64,6 +64,7 @@
</string>
<string name="hint_button">GOT IT!</string>
<string name="arrival_times">Arrival times</string>
+ <string name="no_passages_title">No arrivals found for lines:</string>
<string name="about_history">
<![CDATA[
<h1>Welcome!</h1>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Oct 23, 17:17 (7 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
641376
Default Alt Text
D119.1729696636.diff (44 KB)
Attached To
Mode
D119: Show lines without any arrival times separately
Attached
Detach File
Event Timeline
Log In to Comment