Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F12356947
D136.1775591302.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
32 KB
Referenced Files
None
Subscribers
None
D136.1775591302.diff
View Options
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt b/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt
--- a/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt
@@ -11,11 +11,11 @@
import java.lang.ref.WeakReference
class RouteAdapter(val routes: List<GtfsRoute>,
- click: onItemClick,
- private val layoutId: Int = R.layout.line_title_header) :
+ click: ItemClicker,
+ private val layoutId: Int = R.layout.line_title_header) :
RecyclerView.Adapter<RouteAdapter.ViewHolder>()
{
- val clickreference: WeakReference<onItemClick>
+ val clickreference: WeakReference<ItemClicker>
init {
clickreference = WeakReference(click)
}
@@ -53,7 +53,7 @@
}
}
- fun interface onItemClick{
+ fun interface ItemClicker{
fun onRouteItemClicked(gtfsRoute: GtfsRoute)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt b/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
--- a/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
@@ -7,10 +7,18 @@
import androidx.recyclerview.widget.RecyclerView
import it.reyboz.bustorino.R
import it.reyboz.bustorino.backend.Palina
+import java.lang.ref.WeakReference
-class RouteOnlyLineAdapter (val routeNames: List<String>) :
+class RouteOnlyLineAdapter (val routeNames: List<String>,
+ onItemClick: OnClick?) :
RecyclerView.Adapter<RouteOnlyLineAdapter.ViewHolder>() {
+
+ private val clickreference: WeakReference<OnClick>?
+ init {
+ clickreference = if(onItemClick!=null) WeakReference(onItemClick) else null
+ }
+
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder)
@@ -23,7 +31,7 @@
textView = view.findViewById(R.id.routeBallID)
}
}
- constructor(palina: Palina, showOnlyEmpty: Boolean): this(palina.routesNamesWithNoPassages)
+ constructor(palina: Palina, showOnlyEmpty: Boolean): this(palina.routesNamesWithNoPassages, null)
// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
@@ -40,9 +48,15 @@
// Get element from your dataset at this position and replace the
// contents of the view with that element
viewHolder.textView.text = routeNames[position]
+ viewHolder.itemView.setOnClickListener{
+ clickreference?.get()?.onItemClick(position, routeNames[position])
+ }
}
// Return the size of your dataset (invoked by the layout manager)
override fun getItemCount() = routeNames.size
+ fun interface OnClick{
+ fun onItemClick(index: Int, name: String)
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/GtfsRepository.kt b/app/src/main/java/it/reyboz/bustorino/data/GtfsRepository.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/GtfsRepository.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/GtfsRepository.kt
@@ -35,4 +35,8 @@
fun getAllRoutes(): LiveData<List<GtfsRoute>>{
return gtfsDao.getAllRoutes()
}
+
+ fun getRouteFromGtfsId(gtfsId: String): LiveData<GtfsRoute>{
+ return gtfsDao.getRouteByGtfsID(gtfsId)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java b/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java
--- a/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java
+++ b/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java
@@ -19,12 +19,16 @@
import android.content.Context;
import android.content.SharedPreferences;
+import android.util.Log;
import it.reyboz.bustorino.R;
import static android.content.Context.MODE_PRIVATE;
import androidx.preference.PreferenceManager;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Static class for commonly used SharedPreference operations
*/
@@ -33,6 +37,8 @@
public static final String PREF_GTFS_DB_VERSION = "gtfs_db_version";
public static final String PREF_INTRO_ACTIVITY_RUN ="pref_intro_activity_run";
+ public static final String PREF_FAVORITE_LINES = "pref_favorite_lines";
+
public static SharedPreferences getMainSharedPreferences(Context context){
return context.getSharedPreferences(context.getString(R.string.mainSharedPreferences), MODE_PRIVATE);
}
@@ -59,4 +65,27 @@
final SharedPreferences pref = getMainSharedPreferences(con);
return pref.getBoolean(PREF_INTRO_ACTIVITY_RUN, false);
}
+
+ public static boolean addOrRemoveLineToFavorites(Context con, String gtfsLineId, boolean addToFavorites){
+ final SharedPreferences pref = getMainSharedPreferences(con);
+ final HashSet<String> favorites = new HashSet<>(pref.getStringSet(PREF_FAVORITE_LINES, new HashSet<>()));
+ boolean modified = true;
+ if(addToFavorites)
+ favorites.add(gtfsLineId);
+ else if(favorites.contains(gtfsLineId))
+ favorites.remove(gtfsLineId);
+ else
+ modified = false; // we are not changing anything
+ if(modified) {
+ final SharedPreferences.Editor editor = pref.edit();
+ editor.putStringSet(PREF_FAVORITE_LINES, favorites);
+ editor.apply();
+ }
+ return modified;
+ }
+
+ public static HashSet<String> getFavoritesLinesGtfsIDs(Context con){
+ final SharedPreferences pref = getMainSharedPreferences(con);
+ return new HashSet<>(pref.getStringSet(PREF_FAVORITE_LINES, new HashSet<>()));
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsDBDao.kt
@@ -26,8 +26,8 @@
@Query("SELECT * FROM "+GtfsRoute.DB_TABLE)
fun getAllRoutes() : LiveData<List<GtfsRoute>>
- @Query("SELECT * FROM ${GtfsRoute.DB_TABLE} WHERE ${GtfsRoute.COL_ROUTE_ID} IN (:routeGtfsIds)")
- fun getRoutesByIDs(routeGtfsIds: List<String>): LiveData<List<GtfsRoute>>
+ @Query("SELECT * FROM ${GtfsRoute.DB_TABLE} WHERE ${GtfsRoute.COL_ROUTE_ID} LIKE :gtfsId")
+ fun getRouteByGtfsID(gtfsId: String) : LiveData<GtfsRoute>
@Query("SELECT "+GtfsTrip.COL_TRIP_ID+" FROM "+GtfsTrip.DB_TABLE)
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
@@ -409,7 +409,7 @@
final ArrayList<String> routesWithNoPassages = lastUpdatedPalina.getRoutesNamesWithNoPassages();
Collections.sort(routesWithNoPassages, new LinesNameSorter());
- noArrivalsAdapter = new RouteOnlyLineAdapter(routesWithNoPassages);
+ noArrivalsAdapter = new RouteOnlyLineAdapter(routesWithNoPassages, null);
if(noArrivalsRecyclerView!=null){
noArrivalsRecyclerView.setAdapter(noArrivalsAdapter);
//hide the views if there are no empty routes
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
@@ -20,6 +20,7 @@
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
+import android.content.SharedPreferences
import android.graphics.Paint
import android.os.Bundle
import android.util.Log
@@ -45,6 +46,7 @@
import it.reyboz.bustorino.backend.gtfs.PolylineParser
import it.reyboz.bustorino.backend.utils
import it.reyboz.bustorino.data.MatoTripsDownloadWorker
+import it.reyboz.bustorino.data.PreferencesHolder
import it.reyboz.bustorino.data.gtfs.MatoPattern
import it.reyboz.bustorino.data.gtfs.MatoPatternWithStops
import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops
@@ -67,7 +69,7 @@
class LinesDetailFragment() : ScreenBaseFragment() {
- private lateinit var lineID: String
+ private var lineID = ""
private lateinit var patternsSpinner: Spinner
private var patternsAdapter: ArrayAdapter<String>? = null
@@ -83,7 +85,31 @@
private var firstInit = true
private var pausedFragment = false
private lateinit var switchButton: ImageButton
+
+ private var favoritesButton: ImageButton? = null
+ private var isLineInFavorite = false
+ private val lineSharedPrefMonitor = SharedPreferences.OnSharedPreferenceChangeListener { pref, keychanged ->
+ if(keychanged!=PreferencesHolder.PREF_FAVORITE_LINES || lineID.isEmpty()) return@OnSharedPreferenceChangeListener
+ val newFavorites = pref.getStringSet(PreferencesHolder.PREF_FAVORITE_LINES, HashSet())
+ newFavorites?.let {
+ isLineInFavorite = it.contains(lineID)
+ //if the button has been intialized, change the icon accordingly
+ favoritesButton?.let { button->
+ if(isLineInFavorite) {
+ button.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_star_filled, null))
+ Toast.makeText(context,R.string.favorites_line_add,Toast.LENGTH_SHORT).show()
+ } else {
+ button.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_star_outline, null))
+ Toast.makeText(context,R.string.favorites_line_remove,Toast.LENGTH_SHORT).show()
+ }
+
+
+ }
+ }
+ }
+
private lateinit var stopsRecyclerView: RecyclerView
+ private lateinit var descripTextView: TextView
//adapter for recyclerView
private val stopAdapterListener= object : StopAdapterListener {
override fun onTappedStop(stop: Stop?) {
@@ -93,7 +119,7 @@
viewModel.shouldShowMessage=false
}
stop?.let {
- fragmentListener?.requestArrivalsForStopID(it.ID)
+ fragmentListener.requestArrivalsForStopID(it.ID)
}
if(stop == null){
Log.e(DEBUG_TAG,"Passed wrong stop")
@@ -142,12 +168,27 @@
val rootView = inflater.inflate(R.layout.fragment_lines_detail, container, false)
lineID = requireArguments().getString(LINEID_KEY, "")
switchButton = rootView.findViewById(R.id.switchImageButton)
+ favoritesButton = rootView.findViewById(R.id.favoritesButton)
stopsRecyclerView = rootView.findViewById(R.id.patternStopsRecyclerView)
+ descripTextView = rootView.findViewById(R.id.lineDescripTextView)
+ descripTextView.visibility = View.INVISIBLE
val titleTextView = rootView.findViewById<TextView>(R.id.titleTextView)
-
titleTextView.text = getString(R.string.line)+" "+GtfsUtils.getLineNameFromGtfsID(lineID)
+ favoritesButton?.isClickable = true
+ favoritesButton?.setOnClickListener {
+ if(lineID.isNotEmpty())
+ PreferencesHolder.addOrRemoveLineToFavorites(requireContext(),lineID,!isLineInFavorite)
+ }
+ val preferences = PreferencesHolder.getMainSharedPreferences(requireContext())
+ val favorites = preferences.getStringSet(PreferencesHolder.PREF_FAVORITE_LINES, HashSet())
+ if(favorites!=null && favorites.contains(lineID)){
+ favoritesButton?.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_star_filled, null))
+ isLineInFavorite = true
+ }
+ preferences.registerOnSharedPreferenceChangeListener(lineSharedPrefMonitor)
+
patternsSpinner = rootView.findViewById(R.id.patternsSpinner)
patternsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, ArrayList<String>())
patternsSpinner.adapter = patternsAdapter
@@ -195,6 +236,10 @@
showStopsAsList(stops)
}
}
+ viewModel.gtfsRoute.observe(viewLifecycleOwner){route->
+ descripTextView.text = route.longName
+ descripTextView.visibility = View.VISIBLE
+ }
if(pausedFragment && viewModel.selectedPatternLiveData.value!=null){
val patt = viewModel.selectedPatternLiveData.value!!
Log.d(DEBUG_TAG, "Recreating views on resume, setting pattern: ${patt.pattern.code}")
@@ -310,7 +355,7 @@
// add ability to zoom with 2 fingers
it.setMultiTouchControls(true)
- it.minZoomLevel = 11.0
+ it.minZoomLevel = 12.0
//map controller setup
val mapController = it.controller
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
@@ -15,7 +15,9 @@
import androidx.recyclerview.widget.RecyclerView
import it.reyboz.bustorino.R
import it.reyboz.bustorino.adapters.RouteAdapter
+import it.reyboz.bustorino.adapters.RouteOnlyLineAdapter
import it.reyboz.bustorino.backend.utils
+import it.reyboz.bustorino.data.PreferencesHolder
import it.reyboz.bustorino.data.gtfs.GtfsRoute
import it.reyboz.bustorino.middleware.AutoFitGridLayoutManager
import it.reyboz.bustorino.util.LinesNameSorter
@@ -29,11 +31,12 @@
private val viewModel: LinesGridShowingViewModel by viewModels()
//private lateinit var gridLayoutManager: AutoFitGridLayoutManager
-
+ private lateinit var favoritesRecyclerView: RecyclerView
private lateinit var urbanRecyclerView: RecyclerView
private lateinit var extraurbanRecyclerView: RecyclerView
private lateinit var touristRecyclerView: RecyclerView
+ private lateinit var favoritesTitle: TextView
private lateinit var urbanLinesTitle: TextView
private lateinit var extrurbanLinesTitle: TextView
private lateinit var touristLinesTitle: TextView
@@ -53,7 +56,7 @@
return@Comparator linesNameSorter.compare(a.shortName, b.shortName)
}
- private val routeClickListener = RouteAdapter.onItemClick {
+ private val routeClickListener = RouteAdapter.ItemClicker {
fragmentListener.showLineOnMap(it.gtfsId)
}
private val arrows = HashMap<String, ImageView>()
@@ -66,10 +69,12 @@
): View? {
val rootView = inflater.inflate(R.layout.fragment_lines_grid, container, false)
+ favoritesRecyclerView = rootView.findViewById(R.id.favoritesRecyclerView)
urbanRecyclerView = rootView.findViewById(R.id.urbanLinesRecyclerView)
extraurbanRecyclerView = rootView.findViewById(R.id.extraurbanLinesRecyclerView)
touristRecyclerView = rootView.findViewById(R.id.touristLinesRecyclerView)
+ favoritesTitle = rootView.findViewById(R.id.favoritesTitleView)
urbanLinesTitle = rootView.findViewById(R.id.urbanLinesTitleView)
extrurbanLinesTitle = rootView.findViewById(R.id.extraurbanLinesTitleView)
touristLinesTitle = rootView.findViewById(R.id.touristLinesTitleView)
@@ -77,6 +82,7 @@
arrows[AG_URBAN] = rootView.findViewById(R.id.arrowUrb)
arrows[AG_TOUR] = rootView.findViewById(R.id.arrowTourist)
arrows[AG_EXTRAURB] = rootView.findViewById(R.id.arrowExtraurban)
+ arrows[AG_FAV] = rootView.findViewById(R.id.arrowFavorites)
//show urban expanded by default
val recViews = listOf(urbanRecyclerView, extraurbanRecyclerView, touristRecyclerView)
@@ -87,6 +93,13 @@
)
recyView.layoutManager = gridLayoutManager
}
+ //init favorites recyclerview
+ val gridLayoutManager = AutoFitGridLayoutManager(
+ requireContext().applicationContext,
+ (utils.convertDipToPixels(context, 70f)).toInt()
+ )
+ favoritesRecyclerView.layoutManager = gridLayoutManager
+
viewModel.routesLiveData.observe(viewLifecycleOwner){
//routesList = ArrayList(it)
@@ -116,6 +129,15 @@
}
}
+ viewModel.favoritesLines.observe(viewLifecycleOwner){ routes->
+ val routesNames = routes.map { it.shortName }
+ //create new item click listener every time
+ val adapter = RouteOnlyLineAdapter(routesNames){ pos, _ ->
+ val r = routes[pos]
+ fragmentListener.showLineOnMap(r.gtfsId)
+ }
+ favoritesRecyclerView.adapter = adapter
+ }
//onClicks
urbanLinesTitle.setOnClickListener {
@@ -127,14 +149,33 @@
touristLinesTitle.setOnClickListener {
openLinesAndCloseOthersIfNeeded(AG_TOUR)
}
+ favoritesTitle.setOnClickListener {
+ closeOpenFavorites()
+ }
+ arrows[AG_FAV]?.setOnClickListener {
+ closeOpenFavorites()
+ }
//arrows onClicks
- for(k in arrows.keys){
+ for(k in Companion.AGENCIES){
//k is either AG_TOUR, AG_EXTRAURBAN, AG_URBAN
arrows[k]?.setOnClickListener { openLinesAndCloseOthersIfNeeded(k) }
}
+
return rootView
}
+ private fun closeOpenFavorites(){
+ if(favoritesRecyclerView.visibility == View.VISIBLE){
+ //close it
+ favoritesRecyclerView.visibility = View.GONE
+ setOpen(arrows[AG_FAV]!!, false)
+ viewModel.favoritesExpanded.value = false
+ } else{
+ favoritesRecyclerView.visibility = View.VISIBLE
+ setOpen(arrows[AG_FAV]!!, true)
+ viewModel.favoritesExpanded.value = true
+ }
+ }
private fun openLinesAndCloseOthersIfNeeded(agency: String){
if(openRecyclerView!="" && openRecyclerView!= agency) {
@@ -205,6 +246,20 @@
override fun onResume() {
super.onResume()
+ val pref = PreferencesHolder.getMainSharedPreferences(requireContext())
+ val res = pref.getStringSet(PreferencesHolder.PREF_FAVORITE_LINES, HashSet())
+ res?.let { viewModel.setFavoritesLinesIDs(HashSet(it))}
+ //restore state
+ viewModel.favoritesExpanded.value?.let {
+ if(!it){
+ //close it
+ favoritesRecyclerView.visibility = View.GONE
+ setOpen(arrows[AG_FAV]!!, false)
+ } else{
+ favoritesRecyclerView.visibility = View.VISIBLE
+ setOpen(arrows[AG_FAV]!!, true)
+ }
+ }
viewModel.isUrbanExpanded.value?.let {
if(it) {
urbanRecyclerView.visibility = View.VISIBLE
@@ -246,6 +301,7 @@
companion object {
private const val COLUMN_WIDTH_DP=200
+ private const val AG_FAV = "fav"
private const val AG_URBAN = "gtt:U"
private const val AG_EXTRAURB ="gtt:E"
private const val AG_TOUR ="gtt:T"
diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt
--- a/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt
+++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt
@@ -4,10 +4,11 @@
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
+import androidx.lifecycle.map
import it.reyboz.bustorino.data.GtfsRepository
-import it.reyboz.bustorino.data.NextGenDB
-import it.reyboz.bustorino.data.OldDataRepository
import it.reyboz.bustorino.data.gtfs.GtfsDatabase
+import it.reyboz.bustorino.data.gtfs.GtfsRoute
+import it.reyboz.bustorino.util.LinesNameSorter
class LinesGridShowingViewModel(application: Application) : AndroidViewModel(application) {
@@ -24,4 +25,27 @@
val isUrbanExpanded = MutableLiveData(true)
val isExtraUrbanExpanded = MutableLiveData(false)
val isTouristExpanded = MutableLiveData(false)
+ val favoritesExpanded = MutableLiveData(true)
+
+ val favoritesLinesIDs = MutableLiveData<HashSet<String>>()
+
+ private val linesNameSorter = LinesNameSorter()
+ private val linesComparator = Comparator<GtfsRoute> { a,b ->
+ return@Comparator linesNameSorter.compare(a.shortName, b.shortName)
+ }
+
+ fun setFavoritesLinesIDs(linesIds: HashSet<String>){
+ favoritesLinesIDs.value = linesIds
+ }
+
+ val favoritesLines = favoritesLinesIDs.map {lineIds ->
+ val linesList = ArrayList<GtfsRoute>()
+ if (lineIds.size == 0 || routesLiveData.value==null) return@map linesList
+ for(line in routesLiveData.value!!){
+ if(lineIds.contains(line.gtfsId))
+ linesList.add(line)
+ }
+ linesList.sortWith(linesComparator)
+ return@map linesList
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesViewModel.kt
--- a/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesViewModel.kt
+++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesViewModel.kt
@@ -52,6 +52,9 @@
gtfsRepo.getPatternsWithStopsForRouteID(it)
}
+ val gtfsRoute = routeIDToSearch.switchMap {
+ gtfsRepo.getRouteFromGtfsId(it)
+ }
fun setRouteIDQuery(routeID: String){
diff --git a/app/src/main/res/drawable/ic_star_filled.xml b/app/src/main/res/drawable/ic_star_filled.xml
--- a/app/src/main/res/drawable/ic_star_filled.xml
+++ b/app/src/main/res/drawable/ic_star_filled.xml
@@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="28dp"
+ android:height="28dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
diff --git a/app/src/main/res/drawable/ic_star_outline.xml b/app/src/main/res/drawable/ic_star_outline.xml
--- a/app/src/main/res/drawable/ic_star_outline.xml
+++ b/app/src/main/res/drawable/ic_star_outline.xml
@@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="28dp"
+ android:height="28dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
diff --git a/app/src/main/res/layout/fragment_lines_detail.xml b/app/src/main/res/layout/fragment_lines_detail.xml
--- a/app/src/main/res/layout/fragment_lines_detail.xml
+++ b/app/src/main/res/layout/fragment_lines_detail.xml
@@ -20,18 +20,58 @@
android:layout_marginTop="8dp" android:gravity="center_horizontal|center_vertical"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp" android:layout_marginEnd="8dp"/>
+ <ImageButton
+ android:src="@drawable/ic_list_30"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:id="@+id/switchImageButton"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ android:layout_margin="6dp"
+ android:backgroundTint="@color/blue_620"
+ />
+ <androidx.cardview.widget.CardView
+ android:layout_width="wrap_content" android:layout_height="30dp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@id/switchImageButton"
+ app:layout_constraintBottom_toBottomOf="@id/switchImageButton"
+ android:id="@+id/starCardView"
+ android:layout_marginStart="10dp"
+ android:minHeight="20sp"
+ android:elevation="10dp"
+ android:padding="5dp">
+ <ImageButton
+ android:id="@+id/favoritesButton"
+ 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>
+ <TextView
+ android:text="DCCII"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:id="@+id/lineDescripTextView"
+ app:layout_constraintTop_toBottomOf="@id/titleTextView"
+ app:layout_constraintLeft_toLeftOf="@id/titleTextView"
+ app:layout_constraintRight_toRightOf="@id/titleTextView"
+ android:textColor="@color/grey_700"
+ android:textSize="16sp"
+ android:maxWidth="300sp"
+ android:layout_marginTop="8dp"/>
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/patternsSpinner"
- app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/routeDescrTextView"
- android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/titleTextView"
+ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/headingToTextView"
+ android:layout_marginTop="4dp" app:layout_constraintTop_toBottomOf="@+id/lineDescripTextView"
android:layout_marginStart="4dp"/>
<TextView
android:text="@string/direction_duep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:id="@+id/routeDescrTextView"
+ android:id="@+id/headingToTextView"
app:layout_constraintStart_toStartOf="parent"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?android:attr/textColorPrimary"
@@ -79,16 +119,7 @@
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
/>-->
- <ImageButton
- android:src="@drawable/ic_list_30"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:id="@+id/switchImageButton"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintBottom_toTopOf="@id/patternsSpinner"
- android:layout_margin="6dp"
- android:backgroundTint="@color/blue_500"
- />
+
<View
android:id="@+id/divider"
diff --git a/app/src/main/res/layout/fragment_lines_grid.xml b/app/src/main/res/layout/fragment_lines_grid.xml
--- a/app/src/main/res/layout/fragment_lines_grid.xml
+++ b/app/src/main/res/layout/fragment_lines_grid.xml
@@ -15,6 +15,44 @@
android:layout_width="match_parent" android:layout_height="match_parent"
android:animateLayoutChanges="true"
>
+ <ImageView
+ android:src="@drawable/baseline_chevron_right_24"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" android:id="@+id/arrowFavorites"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/favoritesTitleView"
+ android:layout_margin="4dp"
+ android:layout_marginStart="16dp"
+ android:rotation="90"
+ />
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/favorites_lines"
+ android:textAppearance="@style/TextAppearance.AppCompat.Body2"
+ android:textSize="@dimen/subtitle_size"
+ android:layout_margin="4dp"
+ android:textColor="@color/black_900"
+ android:gravity="center"
+ android:id="@+id/favoritesTitleView"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintLeft_toRightOf="@id/arrowFavorites"
+ app:layout_constraintBottom_toTopOf="@id/favoritesRecyclerView"
+ android:layout_marginLeft="6dp"
+ app:layout_constraintVertical_bias="0.0"
+ app:layout_constraintVertical_chainStyle="packed"/>
+ <androidx.recyclerview.widget.RecyclerView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/favoritesRecyclerView"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:visibility="visible"
+ app:layout_constraintTop_toBottomOf="@id/favoritesTitleView"
+ app:layout_constraintBottom_toTopOf="@id/urbanLinesTitleView"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintVertical_bias="0.0"
+
+ />
<ImageView
android:src="@drawable/baseline_chevron_right_24"
android:layout_width="wrap_content"
@@ -34,12 +72,12 @@
android:textColor="@color/black_900"
android:gravity="center"
android:id="@+id/urbanLinesTitleView"
- app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/favoritesRecyclerView"
app:layout_constraintLeft_toRightOf="@id/arrowUrb"
app:layout_constraintBottom_toTopOf="@id/urbanLinesRecyclerView"
android:layout_marginLeft="6dp"
app:layout_constraintVertical_bias="0.0"
- app:layout_constraintVertical_chainStyle="packed"/>
+ />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
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
@@ -211,12 +211,15 @@
<string name="pref_shown_startup_def_desc">Tocca per cambiare</string>
<string name="positions_source_pref_title">Fonte posizioni in tempo reale di bus e tram</string>
-
<array name="positions_source_sel">
<item>MaTO (aggiornate più spesso, può non funzionare)</item>
<item>GTFS RT (più stabile)</item>
</array>
+ <string name="favorites_line_add">Linea aggiunta ai preferiti</string>
+ <string name="favorites_line_remove">Linea rimossa dai preferiti</string>
+ <string name="favorites_lines">Preferiti</string>
+
<!-- lines -->
<string name="long_press_stop_4_options">Tocca a lungo la fermata per le opzioni</string>
<string name="remove_all_trips">Rimuovi tutti i trip GTFS</string>
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
@@ -39,7 +39,7 @@
<string name="extraurban_lines">Extra urban lines</string>
<string name="turist_lines">Tourist lines</string>
- <string name="direction_duep">Heading to:</string>
+ <string name="direction_duep">Destination:</string>
<string name="lines_fill">Lines: %1$s</string>
<string name="line_fill">Line: %1$s</string>
<string name="no_passages">No timetable found</string>
@@ -55,6 +55,9 @@
<string name="action_author">Meet the author</string>
<string name="added_in_favorites">Bus stop is now in your favorites</string>
<string name="removed_from_favorites">Bus stop removed from your favorites</string>
+ <string name="favorites_line_add">Added line to favorites</string>
+ <string name="favorites_line_remove">Remove line from favorites</string>
+ <string name="favorites_lines">Favorites</string>
<string name="action_favorites">Favorites</string>
<string name="title_activity_favorites">Favorites</string>
<string name="title_activity_map">Map</string>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 21:48 (6 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1826964
Default Alt Text
D136.1775591302.diff (32 KB)
Attached To
Mode
D136: Add possibility to add line to favorites
Attached
Detach File
Event Timeline
Log In to Comment