diff --git a/app/src/main/java/it/reyboz/bustorino/ActivitySettings.java b/app/src/main/java/it/reyboz/bustorino/ActivitySettings.java --- a/app/src/main/java/it/reyboz/bustorino/ActivitySettings.java +++ b/app/src/main/java/it/reyboz/bustorino/ActivitySettings.java @@ -32,7 +32,7 @@ } } -/** +/* * Interesting thing * Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) * .setAction("Action", null).show(); diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt --- a/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt +++ b/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt @@ -45,7 +45,6 @@ import it.reyboz.bustorino.data.NextGenDB import it.reyboz.bustorino.data.UserDB import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction -import it.reyboz.bustorino.middleware.SearchRequestType import it.reyboz.bustorino.util.LinesNameSorter import it.reyboz.bustorino.viewmodels.ArrivalsViewModel import java.util.* @@ -69,7 +68,7 @@ protected lateinit var timesSourceTextView: TextView protected lateinit var messageTextView: TextView protected lateinit var arrivalsRecyclerView: RecyclerView - private lateinit var mListAdapter: PalinaAdapter + private var mListAdapter: PalinaAdapter? = null private lateinit var resultsLayout : LinearLayout private lateinit var loadingMessageTextView: TextView @@ -135,11 +134,11 @@ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - stopID = arguments!!.getString(KEY_STOP_ID) ?: "" + stopID = requireArguments().getString(KEY_STOP_ID) ?: "" DEBUG_TAG = DEBUG_TAG_ALL + " " + stopID //this might really be null - stopName = arguments!!.getString(KEY_STOP_NAME) + stopName = requireArguments().getString(KEY_STOP_NAME) val arrivalsFragment = this listener = object : OnDBUpdateStatusChangeListener { override fun onDBStatusChanged(updating: Boolean) { @@ -159,7 +158,7 @@ return true } } - prefs = DBStatusManager(context!!.applicationContext, listener) + prefs = DBStatusManager(requireContext().applicationContext, listener) justCreated = true } @@ -178,7 +177,7 @@ loadingMessageTextView = root.findViewById(R.id.loadingMessageTextView) progressBar = root.findViewById(R.id.circularProgressBar) - hideHintButton.setOnClickListener(View.OnClickListener { v: View? -> this.onHideHint(v) }) + hideHintButton.setOnClickListener { v: View? -> this.onHideHint(v) } //theScrollView = root.findViewById(R.id.arrivalsScrollView); // recyclerview holding the arrival times @@ -217,7 +216,7 @@ toggleLastStopToFavorites() }) - val displayName = arguments!!.getString(STOP_TITLE) + val displayName = requireArguments().getString(STOP_TITLE) if (displayName != null) setTextViewMessage( String.format( getString(R.string.passages), displayName @@ -225,7 +224,7 @@ ) - val probablemessage = arguments!!.getString(MESSAGE_TEXT_VIEW) + val probablemessage = requireArguments().getString(MESSAGE_TEXT_VIEW) if (probablemessage != null) { //Log.d("BusTO fragment " + this.getTag(), "We have a possible message here in the savedInstaceState: " + probablemessage); messageTextView.setText(probablemessage) @@ -333,7 +332,8 @@ }*/ mListener.readyGUIfor(FragmentKind.ARRIVALS) - resetListAdapter(mListAdapter) + //fix bug when the list adapter is null + mListAdapter?.let { resetListAdapter(it) } if (noArrivalsAdapter != null) { noArrivalsRecyclerView.adapter = noArrivalsAdapter } @@ -402,28 +402,22 @@ // HINT "HOW TO USE" private fun showHints() { - howDoesItWorkTextView!!.visibility = View.VISIBLE - hideHintButton!!.visibility = View.VISIBLE + howDoesItWorkTextView.visibility = View.VISIBLE + hideHintButton.visibility = View.VISIBLE //actionHelpMenuItem.setVisible(false); } private fun hideHints() { - howDoesItWorkTextView!!.visibility = View.GONE - hideHintButton!!.visibility = View.GONE + howDoesItWorkTextView.visibility = View.GONE + hideHintButton.visibility = View.GONE //actionHelpMenuItem.setVisible(true); } fun onHideHint(v: View?) { hideHints() - ScreenBaseFragment.setOption(requireContext(), OPTION_SHOW_LEGEND, false) + setOption(requireContext(), OPTION_SHOW_LEGEND, false) } - val currentFetchers: ArrayList - /** - * Give the fetchers - * @return the list of the fetchers - */ - get() = ArrayList(this.fetchers) /*val currentFetchersAsArray: Array get() { val arr = arrayOfNulls(fetchers!!.size) @@ -434,7 +428,7 @@ */ fun getCurrentFetchersAsArray(): Array { - val r= fetchers.toTypedArray() ?: emptyArray() + val r= fetchers.toTypedArray() //?: emptyArray() return r } @@ -470,12 +464,10 @@ } else { Collections.sort(routesWithNoPassages, LinesNameSorter()) noArrivalsAdapter = RouteOnlyLineAdapter(routesWithNoPassages, null) - if (noArrivalsRecyclerView != null) { - noArrivalsRecyclerView!!.adapter = noArrivalsAdapter + noArrivalsRecyclerView!!.adapter = noArrivalsAdapter - noArrivalsRecyclerView!!.visibility = View.VISIBLE - noArrivalsTitleView!!.visibility = View.VISIBLE - } + noArrivalsRecyclerView!!.visibility = View.VISIBLE + noArrivalsTitleView!!.visibility = View.VISIBLE } @@ -500,21 +492,21 @@ val updatedFetchers = adjustFetchersToSource(source) if (!updatedFetchers) Log.w(DEBUG_TAG, "Tried to update the source fetcher but it didn't work") val base_message = getString(R.string.times_source_fmt, source_txt) - timesSourceTextView!!.text = base_message - timesSourceTextView!!.visibility = View.VISIBLE + timesSourceTextView.text = base_message + timesSourceTextView.visibility = View.VISIBLE if (p.totalNumberOfPassages > 0) { - timesSourceTextView!!.visibility = View.VISIBLE + timesSourceTextView.visibility = View.VISIBLE } else { - timesSourceTextView!!.visibility = View.INVISIBLE + timesSourceTextView.visibility = View.INVISIBLE } fetchersChangeRequestPending = false } - protected fun adjustFetchersToSource(source: Passaggio.Source?): Boolean { + protected fun adjustFetchersToSource(source: Source?): Boolean { if (source == null) return false var count = 0 - if (source != Passaggio.Source.UNDETERMINED) while (source != fetchers!![0]!!.sourceForFetcher && count < 200) { + if (source != Source.UNDETERMINED) while (source != fetchers[0]!!.sourceForFetcher && count < 200) { //we need to update the fetcher that is requested rotateFetchers() count++ @@ -534,15 +526,15 @@ * It may eventually change the "Add to Favorite" icon */ private fun updateMessage() { - var message: String? = null - if (stopName != null && stopID != null && !stopName!!.isEmpty()) { + var message = "" + if (stopName != null && !stopName!!.isEmpty()) { message = ("$stopID - $stopName") } else if (stopID != null) { message = stopID } else { Log.e("ArrivalsFragm$tag", "NO ID FOR THIS FRAGMENT - something went horribly wrong") } - if (message != null) { + if (message.isNotEmpty()) { setTextViewMessage(getString(R.string.passages, message)) } @@ -559,19 +551,19 @@ when (id) { loaderFavId -> { builder.appendPath("favorites").appendPath(stopID) - cl = CursorLoader(context!!, builder.build(), UserDB.getFavoritesColumnNamesAsArray, null, null, null) + cl = CursorLoader(requireContext(), builder.build(), UserDB.getFavoritesColumnNamesAsArray, null, null, null) } loaderStopId -> { builder.appendPath("stop").appendPath(stopID) cl = CursorLoader( - context!!, builder.build(), arrayOf(NextGenDB.Contract.StopsTable.COL_NAME), + requireContext(), builder.build(), arrayOf(NextGenDB.Contract.StopsTable.COL_NAME), null, null, null ) } else -> { - cl = CursorLoader(context!!, builder.build(), null, null,null,null) + cl = CursorLoader(requireContext(), builder.build(), null, null,null,null) Log.d(DEBUG_TAG, "This is probably going to crash") } } @@ -638,8 +630,8 @@ * @param message the whole message to write in the textView */ fun setTextViewMessage(message: String?) { - messageTextView!!.text = message - messageTextView!!.visibility = View.VISIBLE + messageTextView.text = message + messageTextView.visibility = View.VISIBLE } fun toggleLastStopToFavorites() { @@ -648,7 +640,7 @@ // toggle the status in background AsyncStopFavoriteAction( - context!!.applicationContext, AsyncStopFavoriteAction.Action.TOGGLE + requireContext().applicationContext, AsyncStopFavoriteAction.Action.TOGGLE ) { v: Boolean -> updateStarIconFromLastBusStop(v) }.execute(stop) } else { // this case have no sense, but just immediately update the favorite icon @@ -690,25 +682,25 @@ // check if there is a last Stop - if (stopID == null) { - addToFavorites!!.visibility = View.INVISIBLE + if (stopID.isEmpty()) { + addToFavorites.visibility = View.INVISIBLE } else { // filled or outline? if (stopIsInFavorites) { - addToFavorites!!.setImageResource(R.drawable.ic_star_filled) + addToFavorites.setImageResource(R.drawable.ic_star_filled) } else { - addToFavorites!!.setImageResource(R.drawable.ic_star_outline) + addToFavorites.setImageResource(R.drawable.ic_star_outline) } - addToFavorites!!.visibility = View.VISIBLE + addToFavorites.visibility = View.VISIBLE } } override fun onDestroyView() { //arrivalsRecyclerView = null if (arguments != null) { - arguments!!.putString(SOURCES_TEXT, timesSourceTextView!!.text.toString()) - arguments!!.putString(MESSAGE_TEXT_VIEW, messageTextView!!.text.toString()) + requireArguments().putString(SOURCES_TEXT, timesSourceTextView.text.toString()) + requireArguments().putString(MESSAGE_TEXT_VIEW, messageTextView.text.toString()) } super.onDestroyView() } @@ -783,11 +775,11 @@ @JvmStatic fun getDisplayArrivalsSource(source: Source, context: Context): String{ return when (source) { - Passaggio.Source.GTTJSON -> context.getString(R.string.gttjsonfetcher) - Passaggio.Source.FiveTAPI -> context.getString(R.string.fivetapifetcher) - Passaggio.Source.FiveTScraper -> context.getString(R.string.fivetscraper) - Passaggio.Source.MatoAPI -> context.getString(R.string.source_mato) - Passaggio.Source.UNDETERMINED -> //Don't show the view + Source.GTTJSON -> context.getString(R.string.gttjsonfetcher) + Source.FiveTAPI -> context.getString(R.string.fivetapifetcher) + Source.FiveTScraper -> context.getString(R.string.fivetscraper) + Source.MatoAPI -> context.getString(R.string.source_mato) + Source.UNDETERMINED -> //Don't show the view context.getString(R.string.undetermined_source) } 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 @@ -1172,8 +1172,16 @@ private fun removeVehiclesData(vehs: List){ for(v in vehs){ - if (updatesByVehDict.contains(v)) + if (updatesByVehDict.contains(v)) { updatesByVehDict.remove(v) + if (animatorsByVeh.contains(v)){ + animatorsByVeh[v]?.cancel() + animatorsByVeh.remove(v) + } + } + if (vehShowing==v){ + hideStopBottomSheet() + } } } @@ -1195,6 +1203,7 @@ val vehID = pos.vehicle var animate = false if (vehsOld.contains(vehID)){ + //changing the location of an existing bus //update position only if the starting or the stopping position of the animation are in the view val oldPos = updatesByVehDict[vehID]?.posUpdate val oldPattern = updatesByVehDict[vehID]?.pattern @@ -1219,7 +1228,7 @@ val samePosition = oldPos?.let { (it.latitude==pos.latitude)&&(it.longitude == pos.longitude) }?:false val setPattern = (oldPattern==null) && (patternStops!=null) if((!samePosition)|| setPattern) { - //TODO RESTORE THIS PART + //THIS PART C /*val isPositionInBounds = isInsideVisibleRegion( pos.latitude, pos.longitude, true ) || (oldPos?.let { isInsideVisibleRegion(it.latitude,it.longitude,true) } ?: false) @@ -1229,13 +1238,13 @@ if (skip) { //animate = true // set the pattern data too - updatesByVehDict[vehID]!!.pattern = patternStops?.pattern + updatesByVehDict[vehID]!!.pattern = patternStops!!.pattern //this moves both the icon and the label animateNewPositionMove(pos) } else { //update - updatesByVehDict[vehID] = LivePositionTripPattern(pos,patternStops?.pattern) + updatesByVehDict[vehID] = LivePositionTripPattern(pos,patternStops!!.pattern) /*busLabelSymbolsByVeh[vehID]?.let { it.latLng = LatLng(pos.latitude, pos.longitude) symbolsToUpdate.add(it) @@ -1269,7 +1278,12 @@ for(vehID in vehsOld){ //remove after 2 minutes of inactivity if (updatesByVehDict[vehID]!!.posUpdate.timestamp - currentTimeStamp > 2*60){ + //remove the bus updatesByVehDict.remove(vehID) + if(vehID in animatorsByVeh){ + animatorsByVeh[vehID]?.cancel() + animatorsByVeh.remove(vehID) + } //removeVehicleLabel(vehID) } } @@ -1299,11 +1313,14 @@ override fun onAnimationUpdate(animation: ValueAnimator) { latLng = animation.animatedValue as LatLng //update position on animation - val update = updatesByVehDict[positionUpdate.vehicle]!! - latLng?.let { ll-> + val update = updatesByVehDict[positionUpdate.vehicle] + if(update!=null) latLng?.let { ll-> update.posUpdate.latitude = ll.latitude update.posUpdate.longitude = ll.longitude updatePositionsIcons(false) + } else{ + //The update is null + Log.w(DEBUG_TAG, "The bus position to animate has been removed, but the animator is still running!") } } }) @@ -1337,6 +1354,7 @@ //set the new position as the current one but with the old lat and lng positionUpdate.latitude = posUp.latitude positionUpdate.longitude = posUp.longitude + //this might be null if the updates dict does not contain the vehID updatesByVehDict[vehID]!!.posUpdate = positionUpdate valueAnimator.duration = 300 valueAnimator.interpolator = LinearInterpolator()