From 046f49934fa9d470f3d8f29bfabd407bbccb3d06 Mon Sep 17 00:00:00 2001 From: ialokim Date: Sun, 26 Jan 2020 12:48:39 +0100 Subject: [PATCH] Rearrange directions form --- .../departures/DeparturesActivity.java | 6 +- .../trips/search/DirectionsFragment.kt | 116 +++++------ .../trips/search/DirectionsViewModel.java | 14 +- .../grobox/transportr/ui/TimeDateFragment.kt | 37 +++- app/src/main/res/drawable/ic_action_dot.xml | 7 + app/src/main/res/drawable/ic_trip_arrival.xml | 9 - .../main/res/drawable/ic_trip_departure.xml | 9 - .../res/layout/fragment_directions_form.xml | 114 +++++++---- .../main/res/layout/fragment_time_date.xml | 192 ++++++++++-------- app/src/main/res/menu/directions.xml | 13 -- app/src/main/res/values-ca/strings.xml | 5 +- app/src/main/res/values-da/strings.xml | 7 +- app/src/main/res/values-de/strings.xml | 7 +- app/src/main/res/values-el/strings.xml | 7 +- app/src/main/res/values-eo/strings.xml | 7 +- app/src/main/res/values-es/strings.xml | 7 +- app/src/main/res/values-eu/strings.xml | 7 +- app/src/main/res/values-fa/strings.xml | 7 +- app/src/main/res/values-fr/strings.xml | 7 +- app/src/main/res/values-hu/strings.xml | 7 +- app/src/main/res/values-it/strings.xml | 7 +- app/src/main/res/values-ja/strings.xml | 7 +- app/src/main/res/values-nb/strings.xml | 3 +- app/src/main/res/values-nl/strings.xml | 7 +- app/src/main/res/values-pl/strings.xml | 7 +- app/src/main/res/values-pt-rBR/strings.xml | 6 +- app/src/main/res/values-ru/strings.xml | 7 +- app/src/main/res/values-sv/strings.xml | 7 +- app/src/main/res/values-tr/strings.xml | 3 +- app/src/main/res/values-uk/strings.xml | 7 +- app/src/main/res/values-zh-rTW/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 - 32 files changed, 325 insertions(+), 327 deletions(-) create mode 100644 app/src/main/res/drawable/ic_action_dot.xml delete mode 100644 app/src/main/res/drawable/ic_trip_arrival.xml delete mode 100644 app/src/main/res/drawable/ic_trip_departure.xml delete mode 100644 app/src/main/res/menu/directions.xml diff --git a/app/src/main/java/de/grobox/transportr/departures/DeparturesActivity.java b/app/src/main/java/de/grobox/transportr/departures/DeparturesActivity.java index 9bf3d4668..a8e6121f3 100644 --- a/app/src/main/java/de/grobox/transportr/departures/DeparturesActivity.java +++ b/app/src/main/java/de/grobox/transportr/departures/DeparturesActivity.java @@ -195,7 +195,7 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.action_time: if (calendar == null) calendar = Calendar.getInstance(); - TimeDateFragment fragment = TimeDateFragment.newInstance(calendar); + TimeDateFragment fragment = TimeDateFragment.newInstance(calendar, null); fragment.setTimeDateListener(this); fragment.show(getSupportFragmentManager(), TimeDateFragment.TAG); return true; @@ -215,6 +215,10 @@ public void onTimeAndDateSet(Calendar calendar) { getSupportLoaderManager().restartLoader(LOADER_DEPARTURES, args, this).forceLoad(); } + @Override + public void onDepartureOrArrivalSet(boolean departure) { + } + private synchronized void loadMoreDepartures(boolean later) { Date date = new Date(); int maxDepartures = MAX_DEPARTURES; diff --git a/app/src/main/java/de/grobox/transportr/trips/search/DirectionsFragment.kt b/app/src/main/java/de/grobox/transportr/trips/search/DirectionsFragment.kt index a7b2ef78e..791fe40aa 100644 --- a/app/src/main/java/de/grobox/transportr/trips/search/DirectionsFragment.kt +++ b/app/src/main/java/de/grobox/transportr/trips/search/DirectionsFragment.kt @@ -27,10 +27,10 @@ import android.view.View.* import android.view.animation.Animation import android.view.animation.Animation.RELATIVE_TO_SELF import android.view.animation.TranslateAnimation +import androidx.appcompat.widget.TooltipCompat import androidx.core.content.ContextCompat import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelProviders import de.grobox.transportr.R import de.grobox.transportr.TransportrFragment import de.grobox.transportr.data.locations.FavoriteLocation.FavLocationType @@ -44,6 +44,7 @@ import de.grobox.transportr.utils.Constants.DEPARTURE import de.grobox.transportr.utils.Constants.EXPANDED import de.grobox.transportr.utils.DateUtils import de.grobox.transportr.utils.DateUtils.* +import de.schildbach.pte.dto.Product import kotlinx.android.synthetic.main.fragment_directions_form.* import java.util.* import javax.annotation.ParametersAreNonnullByDefault @@ -58,15 +59,12 @@ class DirectionsFragment : TransportrFragment() { internal lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var viewModel: DirectionsViewModel - private var expandItem: MenuItem? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val v = inflater.inflate(R.layout.fragment_directions_form, container, false) component.inject(this) - setHasOptionsMenu(true) - - viewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(DirectionsViewModel::class.java) + viewModel = ViewModelProvider(activity!!, viewModelFactory).get(DirectionsViewModel::class.java) return v } @@ -89,64 +87,59 @@ class DirectionsFragment : TransportrFragment() { viaLocation.setLocationViewListener(viewModel) toLocation.setLocationViewListener(viewModel) - viewModel.home.observe(this, Observer { homeLocation -> - fromLocation.setHomeLocation(homeLocation) - viaLocation.setHomeLocation(homeLocation) - toLocation.setHomeLocation(homeLocation) + viewModel.home.observe(viewLifecycleOwner, Observer { + fromLocation.setHomeLocation(it) + viaLocation.setHomeLocation(it) + toLocation.setHomeLocation(it) }) - viewModel.work.observe(this, Observer { workLocation -> - fromLocation.setWorkLocation(workLocation) - viaLocation.setWorkLocation(workLocation) - toLocation.setWorkLocation(workLocation) + viewModel.work.observe(viewLifecycleOwner, Observer { + fromLocation.setWorkLocation(it) + viaLocation.setWorkLocation(it) + toLocation.setWorkLocation(it) }) - viewModel.locations.observe(this, Observer { favoriteLocations -> - if (favoriteLocations == null) return@Observer - fromLocation.setFavoriteLocations(favoriteLocations) - viaLocation.setFavoriteLocations(favoriteLocations) - toLocation.setFavoriteLocations(favoriteLocations) + viewModel.locations.observe(viewLifecycleOwner, Observer { + if (it == null) return@Observer + fromLocation.setFavoriteLocations(it) + viaLocation.setFavoriteLocations(it) + toLocation.setFavoriteLocations(it) }) - viewModel.fromLocation.observe(this, Observer { location -> - fromLocation.setLocation(location) - if (location != null) toLocation.requestFocus() + viewModel.fromLocation.observe(viewLifecycleOwner, Observer { + fromLocation.setLocation(it) + if (it != null) toLocation.requestFocus() }) - viewModel.viaLocation.observe(this, Observer { location -> viaLocation.setLocation(location) }) - viewModel.toLocation.observe(this, Observer { location -> toLocation.setLocation(location) }) - viewModel.isDeparture.observe(this, Observer { this.onIsDepartureChanged(it) }) - viewModel.isExpanded.observe(this, Observer { this.onViaVisibleChanged(it) }) - viewModel.calendar.observe(this, Observer { this.onCalendarUpdated(it) }) - viewModel.findGpsLocation.observe(this, Observer { this.onFindGpsLocation(it) }) - viewModel.isFavTrip.observe(this, Observer { this.onFavStatusChanged(it) }) - - favIcon.visibility = VISIBLE - favIcon.setOnClickListener { viewModel.toggleFavTrip() } + viewModel.viaLocation.observe(viewLifecycleOwner, Observer { viaLocation.setLocation(it) }) + viewModel.toLocation.observe(viewLifecycleOwner, Observer { toLocation.setLocation(it) }) + viewModel.isDeparture.observe(viewLifecycleOwner, Observer { this.onIsDepartureChanged(it) }) + viewModel.isExpanded.observe(viewLifecycleOwner, Observer { this.onViaVisibleChanged(it) }) + viewModel.calendar.observe(viewLifecycleOwner, Observer { this.onCalendarUpdated(it) }) + viewModel.findGpsLocation.observe(viewLifecycleOwner, Observer { this.onFindGpsLocation(it) }) + viewModel.isFavTrip.observe(viewLifecycleOwner, Observer { this.onFavStatusChanged(it) }) + viewModel.products.observe(viewLifecycleOwner, Observer { this.onProductsChanged(it) }) - departureIcon.setOnClickListener { viewModel.toggleDeparture() } + favIcon.setOnClickListener { viewModel.toggleFavTrip() } - val onTimeClickListener = OnClickListener { + timeBackground.setOnClickListener { if (viewModel.calendar.value == null) throw IllegalStateException() - val fragment = TimeDateFragment.newInstance(viewModel.calendar.value!!) + val fragment = TimeDateFragment.newInstance(viewModel.calendar.value!!, viewModel.isDeparture.value!!) fragment.setTimeDateListener(viewModel) fragment.show(activity!!.supportFragmentManager, TimeDateFragment.TAG) } - val onTimeLongClickListener = OnLongClickListener { + timeBackground.setOnLongClickListener { viewModel.resetCalender() true } - timeIcon.setOnClickListener(onTimeClickListener) - date.setOnClickListener(onTimeClickListener) - time.setOnClickListener(onTimeClickListener) - - timeIcon.setOnLongClickListener(onTimeLongClickListener) - date.setOnLongClickListener(onTimeLongClickListener) - time.setOnLongClickListener(onTimeLongClickListener) - productsIcon.setOnClickListener { activity?.let { a -> ProductDialogFragment().show(a.supportFragmentManager, ProductDialogFragment.TAG) } } swapIcon.setOnClickListener { swapLocations() } + viaIcon.setOnClickListener { viewModel.toggleIsExpanded() } + + TooltipCompat.setTooltipText(productsIcon, getString(R.string.action_choose_products)) + TooltipCompat.setTooltipText(swapIcon, getString(R.string.action_switch_locations)) + TooltipCompat.setTooltipText(viaIcon, getString(R.string.action_navigation_expand)) } override fun onSaveInstanceState(outState: Bundle) { @@ -166,22 +159,7 @@ class DirectionsFragment : TransportrFragment() { viewModel.setToLocation(toLocation.getLocation()) viewModel.onTimeAndDateSet(savedInstanceState.getSerializable(DATE) as Calendar) } - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.directions, menu) - expandItem = menu.findItem(R.id.action_navigation_expand) - super.onCreateOptionsMenu(menu, inflater) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.action_navigation_expand -> { - viewModel.setIsExpanded(!item.isChecked) - true - } - else -> super.onOptionsItemSelected(item) - } + (activity!!.supportFragmentManager.findFragmentByTag(TimeDateFragment.TAG) as? TimeDateFragment)?.setTimeDateListener(viewModel) } private fun onCalendarUpdated(calendar: Calendar?) { @@ -251,12 +229,11 @@ class DirectionsFragment : TransportrFragment() { } private fun onIsDepartureChanged(isDeparture: Boolean) { - departureIcon.setImageResource(if (isDeparture) R.drawable.ic_trip_departure else R.drawable.ic_trip_arrival) + departure.text = getString(if (isDeparture) R.string.trip_dep else R.string.trip_arr) } private fun onViaVisibleChanged(viaVisible: Boolean) { - expandItem?.isChecked = viaVisible - expandItem?.setIcon(if (viaVisible) R.drawable.ic_action_navigation_unfold_less_white else R.drawable.ic_action_navigation_unfold_more_white) + viaIcon?.setImageResource(if (viaVisible) R.drawable.ic_action_navigation_unfold_less_white else R.drawable.ic_action_navigation_unfold_more_white) viaCard.visibility = if (viaVisible) VISIBLE else GONE } @@ -271,7 +248,7 @@ class DirectionsFragment : TransportrFragment() { } fromLocation.setSearching() toLocation.requestFocus() - viewModel.locationLiveData.observe(this, Observer { location -> + viewModel.locationLiveData.observe(viewLifecycleOwner, Observer { location -> viewModel.setFromLocation(location) viewModel.search() viewModel.locationLiveData.removeObservers(this@DirectionsFragment) @@ -283,12 +260,15 @@ class DirectionsFragment : TransportrFragment() { favIcon.visibility = INVISIBLE } else { favIcon.visibility = VISIBLE - if (isFav) { - favIcon.setImageResource(R.drawable.ic_action_star) - } else { - favIcon.setImageResource(R.drawable.ic_action_star_empty) - } + favIcon.setImageResource(if (isFav) R.drawable.ic_action_star else R.drawable.ic_action_star_empty) + val tooltip = getString(if (isFav) R.string.action_unfav_trip else R.string.action_fav_trip) + favIcon.contentDescription = tooltip + TooltipCompat.setTooltipText(favIcon, tooltip) } } + private fun onProductsChanged(products: EnumSet) { + productsMarked.visibility = if (Product.ALL == products) GONE else VISIBLE + } + } diff --git a/app/src/main/java/de/grobox/transportr/trips/search/DirectionsViewModel.java b/app/src/main/java/de/grobox/transportr/trips/search/DirectionsViewModel.java index fb5dcee7f..797735b54 100644 --- a/app/src/main/java/de/grobox/transportr/trips/search/DirectionsViewModel.java +++ b/app/src/main/java/de/grobox/transportr/trips/search/DirectionsViewModel.java @@ -137,6 +137,12 @@ public void onTimeAndDateSet(Calendar calendar) { search(); } + @Override + public void onDepartureOrArrivalSet(boolean departure) { + setIsDeparture(departure); + search(); + } + void resetCalender() { now.setValue(true); search(); @@ -164,11 +170,6 @@ LiveData getIsDeparture() { return isDeparture; } - void toggleDeparture() { - isDeparture.setValue(!(isDeparture.getValue() == null || isDeparture.getValue())); - search(); - } - void setIsDeparture(boolean departure) { isDeparture.setValue(departure); search(); @@ -182,6 +183,8 @@ void setIsExpanded(boolean expanded) { isExpanded.setValue(expanded); } + void toggleIsExpanded() { isExpanded.setValue(!isExpanded.getValue());} + MutableLiveData isFavTrip() { return tripsRepository.isFavTrip(); } @@ -265,5 +268,4 @@ LiveData> getQueryPTEError() { LiveData getQueryMoreError() { return tripsRepository.getQueryMoreError(); } - } diff --git a/app/src/main/java/de/grobox/transportr/ui/TimeDateFragment.kt b/app/src/main/java/de/grobox/transportr/ui/TimeDateFragment.kt index 664db1550..ca3bc5533 100755 --- a/app/src/main/java/de/grobox/transportr/ui/TimeDateFragment.kt +++ b/app/src/main/java/de/grobox/transportr/ui/TimeDateFragment.kt @@ -25,6 +25,7 @@ import android.os.Bundle import android.text.format.DateFormat.getDateFormat import android.view.LayoutInflater import android.view.View +import android.view.View.GONE import android.view.ViewGroup import android.widget.DatePicker import android.widget.TimePicker @@ -38,19 +39,22 @@ import java.util.Calendar.* class TimeDateFragment : DialogFragment(), OnDateSetListener, OnTimeChangedListener { private var listener: TimeDateListener? = null + private var departure: Boolean? = null private lateinit var calendar: Calendar companion object { @JvmField val TAG: String = TimeDateFragment::class.java.simpleName private val CALENDAR = "calendar" + private val DEPARTURE = "departure" @JvmStatic - fun newInstance(calendar: Calendar): TimeDateFragment { + fun newInstance(calendar: Calendar, departure: Boolean? = null): TimeDateFragment { val f = TimeDateFragment() val args = Bundle() args.putSerializable(CALENDAR, calendar) + args.putSerializable(DEPARTURE, departure) f.arguments = args return f @@ -60,12 +64,14 @@ class TimeDateFragment : DialogFragment(), OnDateSetListener, OnTimeChangedListe override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - calendar = if (savedInstanceState == null) { + if (savedInstanceState == null) { arguments?.let { - it.getSerializable(CALENDAR) as Calendar + calendar = it.getSerializable(CALENDAR) as Calendar + departure = it.getSerializable(DEPARTURE) as Boolean? } ?: throw IllegalArgumentException("Arguments missing") } else { - savedInstanceState.getSerializable(CALENDAR) as Calendar + calendar = savedInstanceState.getSerializable(CALENDAR) as Calendar + departure = savedInstanceState.getSerializable(DEPARTURE) as Boolean? } } @@ -97,13 +103,34 @@ class TimeDateFragment : DialogFragment(), OnDateSetListener, OnTimeChangedListe showDate(calendar) } + // Departure or Arrival + departure?.let { + departureButton.isChecked = it + arrivalButton.isChecked = !it + + departureButton.setOnClickListener { + departure = departureButton.isChecked + arrivalButton.isChecked = !departure!! + } + + arrivalButton.setOnClickListener { + departure = !arrivalButton.isChecked + departureButton.isChecked = departure!! + } + } ?: run { + departureButton.visibility = GONE + arrivalButton.visibility = GONE + } + // Buttons okButton.setOnClickListener { listener?.onTimeAndDateSet(calendar) + departure?.let { listener?.onDepartureOrArrivalSet(it) } dismiss() } nowButton.setOnClickListener { listener?.onTimeAndDateSet(Calendar.getInstance()) + departure?.let { listener?.onDepartureOrArrivalSet(it) } dismiss() } cancelButton.setOnClickListener { @@ -114,6 +141,7 @@ class TimeDateFragment : DialogFragment(), OnDateSetListener, OnTimeChangedListe override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putSerializable(CALENDAR, calendar) + outState.putSerializable(DEPARTURE, departure) } override fun onTimeChanged(timePicker: TimePicker, hourOfDay: Int, minute: Int) { @@ -155,6 +183,7 @@ class TimeDateFragment : DialogFragment(), OnDateSetListener, OnTimeChangedListe interface TimeDateListener { fun onTimeAndDateSet(calendar: Calendar) + fun onDepartureOrArrivalSet(departure: Boolean) { } } } diff --git a/app/src/main/res/drawable/ic_action_dot.xml b/app/src/main/res/drawable/ic_action_dot.xml new file mode 100644 index 000000000..e4eca3c87 --- /dev/null +++ b/app/src/main/res/drawable/ic_action_dot.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/drawable/ic_trip_arrival.xml b/app/src/main/res/drawable/ic_trip_arrival.xml deleted file mode 100644 index a7b88c3cf..000000000 --- a/app/src/main/res/drawable/ic_trip_arrival.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_trip_departure.xml b/app/src/main/res/drawable/ic_trip_departure.xml deleted file mode 100644 index 0cd27a357..000000000 --- a/app/src/main/res/drawable/ic_trip_departure.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/fragment_directions_form.xml b/app/src/main/res/layout/fragment_directions_form.xml index 9f32c3f2e..813aa41c1 100644 --- a/app/src/main/res/layout/fragment_directions_form.xml +++ b/app/src/main/res/layout/fragment_directions_form.xml @@ -31,11 +31,32 @@ android:contentDescription="@string/action_fav_trip" android:tint="@color/md_white_1000" android:visibility="gone" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" + app:layout_constraintEnd_toStartOf="@+id/swapIcon" + app:layout_constraintTop_toTopOf="@+id/viaIcon" app:srcCompat="@drawable/ic_action_star_empty" tools:visibility="visible"/> + + + + @@ -96,42 +117,56 @@ - + android:clickable="true" + android:focusable="true" + app:layout_constraintTop_toTopOf="@+id/timeIcon" + app:layout_constraintBottom_toBottomOf="@+id/timeIcon" + app:layout_constraintStart_toStartOf="@+id/timeIcon" + app:layout_constraintEnd_toStartOf="@id/timeBarrier"/> + + + @@ -139,15 +174,12 @@ android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="24dp" - android:background="?selectableItemBackgroundBorderless" - android:clickable="true" - android:focusable="true" android:gravity="center" android:text="@string/now" android:textColor="@color/md_grey_300" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/timeBarrier" - app:layout_constraintStart_toEndOf="@+id/timeIcon" + app:layout_constraintStart_toEndOf="@+id/departure" app:layout_constraintTop_toBottomOf="@+id/date"/> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/timeIcon"/> - + diff --git a/app/src/main/res/layout/fragment_time_date.xml b/app/src/main/res/layout/fragment_time_date.xml index 73b639b94..1d6ba4a49 100644 --- a/app/src/main/res/layout/fragment_time_date.xml +++ b/app/src/main/res/layout/fragment_time_date.xml @@ -1,93 +1,123 @@ - + android:layout_height="match_parent"> - + - + - + - + -