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