Changeset View
Changeset View
Standalone View
Standalone View
app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
Show All 21 Lines | |||||
import androidx.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||
import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||
import android.os.Build; | import android.os.Build; | ||||
import android.util.TypedValue; | import android.util.TypedValue; | ||||
import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||
import android.view.View; | import android.view.View; | ||||
import android.view.ViewGroup; | import android.view.ViewGroup; | ||||
import android.widget.ArrayAdapter; | |||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import java.util.Collections; | import java.util.*; | ||||
import java.util.Comparator; | |||||
import java.util.List; | |||||
import java.util.Locale; | |||||
import androidx.recyclerview.widget.RecyclerView; | |||||
import it.reyboz.bustorino.R; | import it.reyboz.bustorino.R; | ||||
import it.reyboz.bustorino.backend.Palina; | import it.reyboz.bustorino.backend.Palina; | ||||
import it.reyboz.bustorino.backend.Passaggio; | import it.reyboz.bustorino.backend.Passaggio; | ||||
import it.reyboz.bustorino.backend.Route; | import it.reyboz.bustorino.backend.Route; | ||||
import it.reyboz.bustorino.backend.utils; | import it.reyboz.bustorino.backend.utils; | ||||
import it.reyboz.bustorino.util.PassaggiSorter; | import it.reyboz.bustorino.util.PassaggiSorter; | ||||
import it.reyboz.bustorino.util.RouteSorterByArrivalTime; | import it.reyboz.bustorino.util.RouteSorterByArrivalTime; | ||||
import org.jetbrains.annotations.NotNull; | |||||
/** | /** | ||||
* This once was a ListView Adapter for BusLine[]. | * This once was a ListView Adapter for BusLine[]. | ||||
* | * | ||||
* Thanks to Framentos developers for the guide: | * Thanks to Framentos developers for the guide: | ||||
* http://www.framentos.com/en/android-tutorial/2012/07/16/listview-in-android-using-custom-listadapter-and-viewcache/# | * http://www.framentos.com/en/android-tutorial/2012/07/16/listview-in-android-using-custom-listadapter-and-viewcache/# | ||||
* | * | ||||
* @author Valerio Bozzolan | * @author Valerio Bozzolan | ||||
* @author Ludovico Pavesi | * @author Ludovico Pavesi | ||||
*/ | */ | ||||
public class PalinaAdapter extends ArrayAdapter<Route> implements SharedPreferences.OnSharedPreferenceChangeListener { | public class PalinaAdapter extends RecyclerView.Adapter<PalinaAdapter.PalinaViewHolder> implements SharedPreferences.OnSharedPreferenceChangeListener { | ||||
private LayoutInflater li; | |||||
private static int row_layout = R.layout.entry_bus_line_passage; | 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 metroBg = R.drawable.route_background_metro; | ||||
private static final int busBg = R.drawable.route_background_bus; | private static final int busBg = R.drawable.route_background_bus; | ||||
private static final int extraurbanoBg = R.drawable.route_background_bus_long_distance; | private static final int extraurbanoBg = R.drawable.route_background_bus_long_distance; | ||||
private static final int busIcon = R.drawable.bus; | private static final int busIcon = R.drawable.bus; | ||||
private static final int trainIcon = R.drawable.subway; | private static final int trainIcon = R.drawable.subway; | ||||
private static final int tramIcon = R.drawable.tram; | private static final int tramIcon = R.drawable.tram; | ||||
private final String KEY_CAPITALIZE; | private final String KEY_CAPITALIZE; | ||||
private Capitalize capit; | private Capitalize capit; | ||||
//private static final int cityIcon = R.drawable.city; | private final List<Route> mRoutes; | ||||
private final AdapterClickListener<Route> mRouteListener; | |||||
// 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>() { | |||||
@NonNull | |||||
@NotNull | |||||
@Override | @Override | ||||
public int compare(Route route, Route t1) { | public PalinaViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { | ||||
LinesNameSorter sorter = new LinesNameSorter(); | View view = LayoutInflater.from(parent.getContext()) | ||||
if(route.getNameForDisplay()!= null){ | .inflate(ROW_LAYOUT, parent, false); | ||||
if(t1.getNameForDisplay()!=null){ | return new PalinaViewHolder(view); | ||||
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); | |||||
} | } | ||||
/** | |||||
* 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 | |||||
@Override | @Override | ||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) { | public void onBindViewHolder(@NonNull @NotNull PalinaViewHolder vh, int position) { | ||||
ViewHolder vh; | final Route route = mRoutes.get(position); | ||||
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); | |||||
// STORE VIEWHOLDER IN\ON\OVER\UNDER\ABOVE\BESIDE THE VIEW! | |||||
convertView.setTag(vh); | |||||
} else { | |||||
// RECOVER THIS STUFF! | |||||
vh = (ViewHolder) convertView.getTag(); | |||||
} | |||||
Route route = getItem(position); | |||||
vh.rowStopIcon.setText(route.getNameForDisplay()); | vh.rowStopIcon.setText(route.getNameForDisplay()); | ||||
if(route.destinazione==null || route.destinazione.length() == 0) { | if(route.destinazione==null || route.destinazione.length() == 0) { | ||||
vh.rowRouteDestination.setVisibility(View.GONE); | vh.rowRouteDestination.setVisibility(View.GONE); | ||||
// move around the route timetable | // move around the route timetable | ||||
final ViewGroup.MarginLayoutParams pars = (ViewGroup.MarginLayoutParams) vh.rowRouteTimetable.getLayoutParams(); | final ViewGroup.MarginLayoutParams pars = (ViewGroup.MarginLayoutParams) vh.rowRouteTimetable.getLayoutParams(); | ||||
if (pars!=null){ | if (pars!=null){ | ||||
pars.topMargin = 16; | pars.topMargin = 16; | ||||
if(Build.VERSION.SDK_INT >= 17) | if(Build.VERSION.SDK_INT >= 17) | ||||
Show All 11 Lines | public void onBindViewHolder(@NonNull @NotNull PalinaViewHolder vh, int position) { | ||||
case FIRST: | case FIRST: | ||||
dest = utils.toTitleCase(route.destinazione, true); | dest = utils.toTitleCase(route.destinazione, true); | ||||
break; | break; | ||||
case DO_NOTHING: | case DO_NOTHING: | ||||
default: | default: | ||||
} | } | ||||
vh.rowRouteDestination.setText(dest); | vh.rowRouteDestination.setText(dest); | ||||
//set click listener | |||||
vh.itemView.setOnClickListener(view -> { | |||||
mRouteListener.onAdapterClickListener(route); | |||||
}); | |||||
} | } | ||||
switch (route.type) { | switch (route.type) { | ||||
//UNKNOWN = BUS for the moment | //UNKNOWN = BUS for the moment | ||||
case UNKNOWN: | case UNKNOWN: | ||||
case BUS: | case BUS: | ||||
default: | default: | ||||
// convertView could contain another background, reset it | // convertView could contain another background, reset it | ||||
Show All 23 Lines | public void onBindViewHolder(@NonNull @NotNull PalinaViewHolder vh, int position) { | ||||
//TODO: Sort the passaggi with realtime first if source is GTTJSONFetcher | //TODO: Sort the passaggi with realtime first if source is GTTJSONFetcher | ||||
if(passaggi.size() == 0) { | if(passaggi.size() == 0) { | ||||
vh.rowRouteTimetable.setText(R.string.no_passages); | vh.rowRouteTimetable.setText(R.string.no_passages); | ||||
} else { | } else { | ||||
vh.rowRouteTimetable.setText(route.getPassaggiToString()); | 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 | @Override | ||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { | ||||
if(key.equals(KEY_CAPITALIZE)){ | if(key.equals(KEY_CAPITALIZE)){ | ||||
capit = getCapitalize(sharedPreferences, KEY_CAPITALIZE); | capit = getCapitalize(sharedPreferences, KEY_CAPITALIZE); | ||||
notifyDataSetChanged(); | notifyDataSetChanged(); | ||||
} | } | ||||
} | } | ||||
enum Capitalize{ | enum Capitalize{ | ||||
DO_NOTHING, ALL, FIRST | DO_NOTHING, ALL, FIRST | ||||
} | } | ||||
} | } |
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