diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt index f1cc0cc..609b22b 100644 --- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt @@ -1,278 +1,281 @@ package it.reyboz.bustorino.fragments import android.content.Context import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.animation.Animation import android.view.animation.LinearInterpolator import android.view.animation.RotateAnimation import android.widget.ImageView import android.widget.TextView import androidx.fragment.app.viewModels import androidx.recyclerview.widget.RecyclerView import it.reyboz.bustorino.R import it.reyboz.bustorino.adapters.RouteAdapter import it.reyboz.bustorino.backend.utils import it.reyboz.bustorino.data.gtfs.GtfsRoute import it.reyboz.bustorino.middleware.AutoFitGridLayoutManager import it.reyboz.bustorino.util.LinesNameSorter import it.reyboz.bustorino.util.ViewUtils import it.reyboz.bustorino.viewmodels.LinesGridShowingViewModel class LinesGridShowingFragment : ScreenBaseFragment() { private val viewModel: LinesGridShowingViewModel by viewModels() //private lateinit var gridLayoutManager: AutoFitGridLayoutManager private lateinit var urbanRecyclerView: RecyclerView private lateinit var extraurbanRecyclerView: RecyclerView private lateinit var touristRecyclerView: RecyclerView private lateinit var urbanLinesTitle: TextView private lateinit var extrurbanLinesTitle: TextView private lateinit var touristLinesTitle: TextView private var routesByAgency = HashMap<String, ArrayList<GtfsRoute>>() /*hashMapOf( AG_URBAN to ArrayList<GtfsRoute>(), AG_EXTRAURB to ArrayList(), AG_TOUR to ArrayList() )*/ private lateinit var fragmentListener: CommonFragmentListener private val linesNameSorter = LinesNameSorter() private val linesComparator = Comparator<GtfsRoute> { a,b -> return@Comparator linesNameSorter.compare(a.shortName, b.shortName) } private val routeClickListener = RouteAdapter.onItemClick { fragmentListener.showLineOnMap(it.gtfsId) } private val arrows = HashMap<String, ImageView>() private val durations = HashMap<String, Long>() private var openRecyclerView = "AG_URBAN" override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val rootView = inflater.inflate(R.layout.fragment_lines_grid, container, false) urbanRecyclerView = rootView.findViewById(R.id.urbanLinesRecyclerView) extraurbanRecyclerView = rootView.findViewById(R.id.extraurbanLinesRecyclerView) touristRecyclerView = rootView.findViewById(R.id.touristLinesRecyclerView) urbanLinesTitle = rootView.findViewById(R.id.urbanLinesTitleView) extrurbanLinesTitle = rootView.findViewById(R.id.extraurbanLinesTitleView) touristLinesTitle = rootView.findViewById(R.id.touristLinesTitleView) arrows[AG_URBAN] = rootView.findViewById(R.id.arrowUrb) arrows[AG_TOUR] = rootView.findViewById(R.id.arrowTourist) arrows[AG_EXTRAURB] = rootView.findViewById(R.id.arrowExtraurban) //show urban expanded by default val recViews = listOf(urbanRecyclerView, extraurbanRecyclerView, touristRecyclerView) for (recyView in recViews) { val gridLayoutManager = AutoFitGridLayoutManager( requireContext().applicationContext, (utils.convertDipToPixels(context, COLUMN_WIDTH_DP.toFloat())).toInt() ) recyView.layoutManager = gridLayoutManager } viewModel.routesLiveData.observe(viewLifecycleOwner){ //routesList = ArrayList(it) //routesList.sortWith(linesComparator) routesByAgency.clear() for(route in it){ val agency = route.agencyID if(!routesByAgency.containsKey(agency)){ routesByAgency[agency] = ArrayList() } routesByAgency[agency]?.add(route) } //val adapter = RouteOnlyLineAdapter(routesByAgency.map { route-> route.shortName }) //zip agencies and recyclerviews Companion.AGENCIES.zip(recViews) { ag, recView -> routesByAgency[ag]?.let { routeList -> routeList.sortWith(linesComparator) //val adapter = RouteOnlyLineAdapter(it.map { rt -> rt.shortName }) val adapter = RouteAdapter(routeList,routeClickListener) recView.adapter = adapter durations[ag] = if(routeList.size < 20) ViewUtils.DEF_DURATION else 1000 } } } //onClicks urbanLinesTitle.setOnClickListener { - if(openRecyclerView!=""&& openRecyclerView!= AG_URBAN){ - openCloseRecyclerView(openRecyclerView) - openCloseRecyclerView(AG_URBAN) - } + openLinesAndCloseOthersIfNeeded(AG_URBAN) } extrurbanLinesTitle.setOnClickListener { - if(openRecyclerView!=""&& openRecyclerView!= AG_EXTRAURB){ - openCloseRecyclerView(openRecyclerView) - openCloseRecyclerView(AG_EXTRAURB) - - } + openLinesAndCloseOthersIfNeeded(AG_EXTRAURB) } touristLinesTitle.setOnClickListener { - if(openRecyclerView!="" && openRecyclerView!= AG_TOUR) { - openCloseRecyclerView(openRecyclerView) - openCloseRecyclerView(AG_TOUR) - } + openLinesAndCloseOthersIfNeeded(AG_TOUR) + } + //arrows onClicks + for(k in arrows.keys){ + //k is either AG_TOUR, AG_EXTRAURBAN, AG_URBAN + arrows[k]?.setOnClickListener { openLinesAndCloseOthersIfNeeded(k) } } return rootView } - private fun openCloseRecyclerView(agency: String){ + private fun openLinesAndCloseOthersIfNeeded(agency: String){ + if(openRecyclerView!="" && openRecyclerView!= agency) { + switchRecyclerViewStatus(openRecyclerView) + + } + switchRecyclerViewStatus(agency) + } + + private fun switchRecyclerViewStatus(agency: String){ val recyclerView = when(agency){ AG_TOUR -> touristRecyclerView AG_EXTRAURB -> extraurbanRecyclerView AG_URBAN -> urbanRecyclerView else -> throw IllegalArgumentException("$DEBUG_TAG: Agency Invalid") } val expandedLiveData = when(agency){ AG_TOUR -> viewModel.isTouristExpanded AG_URBAN -> viewModel.isUrbanExpanded AG_EXTRAURB -> viewModel.isExtraUrbanExpanded else -> throw IllegalArgumentException("$DEBUG_TAG: Agency Invalid") } val duration = durations[agency] val arrow = arrows[agency] val durArrow = if(duration == null || duration==ViewUtils.DEF_DURATION) 500 else duration if(duration!=null&&arrow!=null) when (recyclerView.visibility){ View.GONE -> { Log.d(DEBUG_TAG, "Open recyclerview $agency") //val a =ViewUtils.expand(recyclerView, duration, 0) recyclerView.visibility = View.VISIBLE expandedLiveData.value = true Log.d(DEBUG_TAG, "Arrow for $agency has rotation: ${arrow.rotation}") setOpen(arrow, true) //arrow.startAnimation(rotateArrow(true,durArrow)) openRecyclerView = agency } View.VISIBLE -> { Log.d(DEBUG_TAG, "Close recyclerview $agency") //ViewUtils.collapse(recyclerView, duration) recyclerView.visibility = View.GONE expandedLiveData.value = false //arrow.rotation = 90f Log.d(DEBUG_TAG, "Arrow for $agency has rotation ${arrow.rotation} pre-rotate") setOpen(arrow, false) //arrow.startAnimation(rotateArrow(false,durArrow)) openRecyclerView = "" } View.INVISIBLE -> { TODO() } } } override fun onAttach(context: Context) { super.onAttach(context) if(context is CommonFragmentListener){ fragmentListener = context } else throw RuntimeException("$context must implement CommonFragmentListener") } override fun getBaseViewForSnackBar(): View? { return null } override fun onResume() { super.onResume() viewModel.isUrbanExpanded.value?.let { if(it) { urbanRecyclerView.visibility = View.VISIBLE arrows[AG_URBAN]?.rotation= 90f openRecyclerView = AG_URBAN Log.d(DEBUG_TAG, "RecyclerView gtt:U is expanded") } else { urbanRecyclerView.visibility = View.GONE arrows[AG_URBAN]?.rotation= 0f } } viewModel.isTouristExpanded.value?.let { val recview = touristRecyclerView if(it) { recview.visibility = View.VISIBLE arrows[AG_TOUR]?.rotation=90f openRecyclerView = AG_TOUR } else { recview.visibility = View.GONE arrows[AG_TOUR]?.rotation= 0f } } viewModel.isExtraUrbanExpanded.value?.let { val recview = extraurbanRecyclerView if(it) { openRecyclerView = AG_EXTRAURB recview.visibility = View.VISIBLE arrows[AG_EXTRAURB]?.rotation=90f } else { recview.visibility = View.GONE arrows[AG_EXTRAURB]?.rotation=0f } } fragmentListener.readyGUIfor(FragmentKind.LINES) } companion object { private const val COLUMN_WIDTH_DP=200 private const val AG_URBAN = "gtt:U" private const val AG_EXTRAURB ="gtt:E" private const val AG_TOUR ="gtt:T" private const val DEBUG_TAG ="BusTO-LinesGridFragment" const val FRAGMENT_TAG = "LinesGridShowingFragment" private val AGENCIES = listOf(AG_URBAN, AG_EXTRAURB, AG_TOUR) fun newInstance() = LinesGridShowingFragment() @JvmStatic fun setOpen(imageView: ImageView, value: Boolean){ if(value) imageView.rotation = 90f else imageView.rotation = 0f } @JvmStatic fun rotateArrow(toOpen: Boolean, duration: Long): RotateAnimation{ val start = if (toOpen) 0f else 90f val stop = if(toOpen) 90f else 0f Log.d(DEBUG_TAG, "Rotate arrow from $start to $stop") val rotate = RotateAnimation(start, stop, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f) rotate.duration = duration rotate.interpolator = LinearInterpolator() //rotate.fillAfter = true rotate.fillBefore = false return rotate } } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_lines_grid.xml b/app/src/main/res/layout/fragment_lines_grid.xml index 25e0144..82417b1 100644 --- a/app/src/main/res/layout/fragment_lines_grid.xml +++ b/app/src/main/res/layout/fragment_lines_grid.xml @@ -1,138 +1,138 @@ <?xml version="1.0" encoding="utf-8"?> <FrameLayout 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" tools:context=".fragments.LinesGridShowingFragment"> <!--<androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/linesScrollView" android:layout_weight="12" >--> <androidx.constraintlayout.widget.ConstraintLayout 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/arrowUrb" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="@id/urbanLinesTitleView" android:layout_margin="4dp" android:layout_marginStart="16dp" android:rotation="0" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/urban_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/urbanLinesTitleView" app:layout_constraintTop_toTopOf="parent" 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="spread"/> + app:layout_constraintVertical_chainStyle="packed"/> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="0dp" android:id="@+id/urbanLinesRecyclerView" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:visibility="visible" android:layout_below="@id/urbanLinesTitleView" app:layout_constraintTop_toBottomOf="@id/urbanLinesTitleView" app:layout_constraintBottom_toTopOf="@id/touristLinesTitleView" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintVertical_bias="0.0" /> <ImageView android:src="@drawable/baseline_chevron_right_24" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/arrowTourist" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="@id/touristLinesTitleView" android:layout_margin="4dp" android:layout_marginStart="16dp" android:rotation="0" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/turist_lines" android:textAppearance="@style/TextAppearance.AppCompat.Body2" android:textSize="@dimen/subtitle_size" android:textColor="@color/black_900" android:layout_margin="4dp" android:layout_marginStart="6dp" android:gravity="center" android:id="@+id/touristLinesTitleView" app:layout_constraintLeft_toRightOf="@id/arrowTourist" app:layout_constraintTop_toBottomOf="@id/urbanLinesRecyclerView" app:layout_constraintBottom_toTopOf="@id/touristLinesRecyclerView" app:layout_constraintVertical_bias="0.0" android:layout_marginLeft="6dp"/> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="0dp" android:id="@+id/touristLinesRecyclerView" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:visibility="gone" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/touristLinesTitleView" app:layout_constraintBottom_toTopOf="@id/extraurbanLinesTitleView" app:layout_constraintVertical_bias="0.0" /> <ImageView android:src="@drawable/baseline_chevron_right_24" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/arrowExtraurban" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="@id/extraurbanLinesTitleView" android:layout_margin="4dp" android:layout_marginStart="16dp" android:rotation="0" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/extraurban_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:layout_marginStart="6dp" android:id="@+id/extraurbanLinesTitleView" app:layout_constraintTop_toBottomOf="@id/touristLinesRecyclerView" app:layout_constraintLeft_toRightOf="@id/arrowExtraurban" app:layout_constraintBottom_toTopOf="@id/extraurbanLinesRecyclerView" app:layout_constraintVertical_bias="0.0" /> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="0dp" android:id="@+id/extraurbanLinesRecyclerView" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:visibility="gone" android:layout_below="@id/extraurbanLinesTitleView" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/extraurbanLinesTitleView" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.0" /> </androidx.constraintlayout.widget.ConstraintLayout> <!--</androidx.core.widget.NestedScrollView>--> </FrameLayout> \ No newline at end of file