Replaced custom TimePickerFragment.kt with standard MaterialTimePicker

This commit is contained in:
denizk0461
2023-05-04 13:29:34 +02:00
parent 50c7bfebba
commit 5ca5788899
7 changed files with 73 additions and 114 deletions
@@ -91,6 +91,8 @@ class FetcherActivity : FragmentActivity() {
*/ */
binding.webview.loadUrl("https://elearning.uni-bremen.de/index.php?again=yes") binding.webview.loadUrl("https://elearning.uni-bremen.de/index.php?again=yes")
binding.webview
binding.fab.setOnClickListener { binding.fab.setOnClickListener {
if (binding.webview.url?.contains( if (binding.webview.url?.contains(
@@ -1,62 +0,0 @@
package com.denizk0461.studip.dialog
import android.app.Dialog
import androidx.fragment.app.DialogFragment
import android.app.TimePickerDialog
import android.os.Bundle
import android.os.Parcelable
import android.widget.TimePicker
import com.denizk0461.studip.data.getParcelableCompat
/**
* Dialogue used for letting the user pick a timestamp.
*/
class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener {
private lateinit var listener: OnTimeSetListener
private var isEventStart: Boolean = false
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Retrieve listener for when the user finishes setting a time
listener = arguments.getParcelableCompat("interface")
// Retrieve whether the timestamp to be edited is the start of the event
isEventStart = arguments?.getBoolean("isEventStart") == true
// Retrieve timestamp to edit
val timestampSplit = (arguments?.getString("timestamp") ?: "").split(":")
return TimePickerDialog(
activity,
this,
timestampSplit[0].toInt(),
timestampSplit[1].toInt(),
true,
)
}
/**
* Override the implementation of TimePickerDialog#OnTimeSetListener.
*/
override fun onTimeSet(picker: TimePicker?, hours: Int, minutes: Int) {
// Use custom implementation of OnTimeSetListener
listener.onTimeSet(hours, minutes, isEventStart)
}
/**
* Custom implementation of TimePickerDialog#OnTimeSetListener that includes a boolean to find
* out whether the start or the end timestamp has been edited.
*/
interface OnTimeSetListener : Parcelable {
/**
* Timestamp has been edited by the user.
*
* @param hours hour of the timestamp
* @param minutes minute of the timestamp
* @param isEventStart whether the timestamp to be edited is the start of the event
*/
fun onTimeSet(hours: Int, minutes: Int, isEventStart: Boolean)
}
}
@@ -1,13 +1,10 @@
package com.denizk0461.studip.sheet package com.denizk0461.studip.sheet
import android.os.Bundle import android.os.Bundle
import android.os.Parcel
import android.os.Parcelable
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.widget.addTextChangedListener import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.transition.TransitionManager import androidx.transition.TransitionManager
import com.denizk0461.studip.R import com.denizk0461.studip.R
@@ -19,16 +16,17 @@ import com.denizk0461.studip.data.showToast
import com.denizk0461.studip.data.timeslotsForAcademicQuarter import com.denizk0461.studip.data.timeslotsForAcademicQuarter
import com.denizk0461.studip.data.viewBinding import com.denizk0461.studip.data.viewBinding
import com.denizk0461.studip.databinding.SheetScheduleUpdateBinding import com.denizk0461.studip.databinding.SheetScheduleUpdateBinding
import com.denizk0461.studip.dialog.TimePickerFragment
import com.denizk0461.studip.exception.AcademicQuarterNotApplicableException import com.denizk0461.studip.exception.AcademicQuarterNotApplicableException
import com.denizk0461.studip.exception.ParcelNotFoundException import com.denizk0461.studip.exception.ParcelNotFoundException
import com.denizk0461.studip.model.StudIPEvent import com.denizk0461.studip.model.StudIPEvent
import com.denizk0461.studip.viewmodel.ScheduleUpdateViewModel import com.denizk0461.studip.viewmodel.ScheduleUpdateViewModel
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
/** /**
* Update sheet to allow the user to edit attributes for a specific schedule event. * Update sheet to allow the user to edit attributes for a specific schedule event.
*/ */
class ScheduleUpdateSheet() : AppSheet(R.layout.sheet_schedule_update), TimePickerFragment.OnTimeSetListener { class ScheduleUpdateSheet : AppSheet(R.layout.sheet_schedule_update) {
// Editable fields // Editable fields
private var timeslotStart = "12:00" private var timeslotStart = "12:00"
@@ -50,15 +48,6 @@ class ScheduleUpdateSheet() : AppSheet(R.layout.sheet_schedule_update), TimePick
// Day the event is scheduled for, default is Monday // Day the event is scheduled for, default is Monday
private var selectedDay = 0 private var selectedDay = 0
constructor(parcel: Parcel) : this() {
timeslotStart = parcel.readString() ?: ""
timeslotEnd = parcel.readString() ?: ""
colour = parcel.readInt()
hasClickedDelete = parcel.readByte() != 0.toByte()
isEditing = parcel.readByte() != 0.toByte()
selectedDay = parcel.readInt()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -281,28 +270,26 @@ class ScheduleUpdateSheet() : AppSheet(R.layout.sheet_schedule_update), TimePick
} }
} }
// Prepare timestamp buttons // Prepare timestamp start button
binding.buttonTimeStart.text = timeslotStart binding.buttonTimeStart.text = timeslotStart
binding.buttonTimeStart.setOnClickListener { binding.buttonTimeStart.setOnClickListener {
// Launch a time picker dialogue to pick a new start timestamp // Launch a time picker dialogue to pick a new start timestamp
TimePickerFragment().also { sheet -> createTimePicker(binding.buttonTimeStart.text.toString(), true).also { picker ->
val bundle = Bundle() picker.addOnPositiveButtonClickListener {
bundle.putParcelable("interface", this) onTimeSet(picker.hour, picker.minute, true)
bundle.putBoolean("isEventStart", true) }
bundle.putString("timestamp", binding.buttonTimeStart.text.toString()) }.show(childFragmentManager, "timePickerStart")
sheet.arguments = bundle
}.show((context as FragmentActivity).supportFragmentManager, "timePicker")
} }
// Prepare timestamp end button
binding.buttonTimeEnd.text = timeslotEnd binding.buttonTimeEnd.text = timeslotEnd
binding.buttonTimeEnd.setOnClickListener { binding.buttonTimeEnd.setOnClickListener {
// Launch a time picker dialogue to pick a new end timestamp // Launch a time picker dialogue to pick a new end timestamp
TimePickerFragment().also { sheet -> createTimePicker(binding.buttonTimeEnd.text.toString(), false).also { picker ->
val bundle = Bundle() picker.addOnPositiveButtonClickListener {
bundle.putParcelable("interface", this) onTimeSet(picker.hour, picker.minute, false)
bundle.putBoolean("isEventStart", false) }
bundle.putString("timestamp", binding.buttonTimeEnd.text.toString()) }.show(childFragmentManager, "timePickerEnd")
sheet.arguments = bundle
}.show((context as FragmentActivity).supportFragmentManager, "timePicker")
} }
// Set up close button // Set up close button
@@ -313,13 +300,13 @@ class ScheduleUpdateSheet() : AppSheet(R.layout.sheet_schedule_update), TimePick
} }
/** /**
* Checks and stores a new timestamp after the user picks one through [TimePickerFragment]. * Checks and stores a new timestamp after the user picks one through [MaterialTimePicker].
* *
* @param hours newly set hour * @param hours newly set hour
* @param minutes newly set minute * @param minutes newly set minute
* @param isEventStart whether this timestamp is for the start of the course * @param isEventStart whether this timestamp is for the start of the course
*/ */
override fun onTimeSet(hours: Int, minutes: Int, isEventStart: Boolean) { private fun onTimeSet(hours: Int, minutes: Int, isEventStart: Boolean) {
// Parse the separate ints into a timestamp string. Add a leading zero if necessary. // Parse the separate ints into a timestamp string. Add a leading zero if necessary.
val newTimestamp = "$hours:${String.format("%02d", minutes)}" val newTimestamp = "$hours:${String.format("%02d", minutes)}"
@@ -408,26 +395,24 @@ class ScheduleUpdateSheet() : AppSheet(R.layout.sheet_schedule_update), TimePick
View.GONE View.GONE
} }
override fun writeToParcel(parcel: Parcel, flags: Int) { /**
parcel.writeString(timeslotStart) * Creates a new time picker dialog.
parcel.writeString(timeslotEnd) *
parcel.writeInt(colour) * @param timestamp timestamp to edit
parcel.writeByte(if (hasClickedDelete) 1 else 0) * @param isEventStart whether the user is editing the start or the end of the event
parcel.writeByte(if (isEditing) 1 else 0) * @return new [MaterialTimePicker]
parcel.writeInt(selectedDay) */
} private fun createTimePicker(timestamp: String, isEventStart: Boolean): MaterialTimePicker {
val timestampSplit = timestamp.split(":")
override fun describeContents(): Int { return MaterialTimePicker.Builder()
return 0 .setTimeFormat(TimeFormat.CLOCK_24H)
} .setHour(timestampSplit[0].toInt())
.setMinute(timestampSplit[1].toInt())
companion object CREATOR : Parcelable.Creator<ScheduleUpdateSheet> { .setTitleText(getString(if (isEventStart) {
override fun createFromParcel(parcel: Parcel): ScheduleUpdateSheet { R.string.sheet_schedule_update_time_dialog_start_hint
return ScheduleUpdateSheet(parcel) } else {
} R.string.sheet_schedule_update_time_dialog_end_hint
}))
override fun newArray(size: Int): Array<ScheduleUpdateSheet?> { .build()
return arrayOfNulls(size)
}
} }
} }
+2
View File
@@ -53,6 +53,8 @@
<string name="sheet_schedule_update_timestamp_error_start">Der Kurs kann nicht anfangen nachdem er aufhört!</string> <string name="sheet_schedule_update_timestamp_error_start">Der Kurs kann nicht anfangen nachdem er aufhört!</string>
<string name="sheet_schedule_update_timestamp_error_end">Der Kurs kann nicht enden bevor er anfängt!</string> <string name="sheet_schedule_update_timestamp_error_end">Der Kurs kann nicht enden bevor er anfängt!</string>
<string name="sheet_schedule_update_text_field_empty_error">Dieses Feld darf nicht leer sein</string> <string name="sheet_schedule_update_text_field_empty_error">Dieses Feld darf nicht leer sein</string>
<string name="sheet_schedule_update_time_dialog_start_hint">Startzeit der Veranstaltung</string>
<string name="sheet_schedule_update_time_dialog_end_hint">Schlusszeit der Veranstaltung</string>
<string name="canteen_no_offer_header">Kein Angebot</string> <string name="canteen_no_offer_header">Kein Angebot</string>
<string name="canteen_no_offer_desc">Für diesen Tag sind keine Angebote vorhanden</string> <string name="canteen_no_offer_desc">Für diesen Tag sind keine Angebote vorhanden</string>
+15
View File
@@ -80,9 +80,24 @@
<item name="colorOnPrimaryGame">@color/game_dark_onPrimary</item> <item name="colorOnPrimaryGame">@color/game_dark_onPrimary</item>
<item name="colorContainerGame">@color/game_dark_container</item> <item name="colorContainerGame">@color/game_dark_container</item>
<item name="colorOnContainerGame">@color/game_dark_onContainer</item> <item name="colorOnContainerGame">@color/game_dark_onContainer</item>
<item name="materialTimePickerTheme">@style/TimeDialogTheme</item>
</style> </style>
<style name="DividerTheme" parent="Widget.Material3.MaterialDivider"> <style name="DividerTheme" parent="Widget.Material3.MaterialDivider">
<item name="dividerColor">@color/md_theme_dark_outlineVariant</item> <item name="dividerColor">@color/md_theme_dark_outlineVariant</item>
</style> </style>
<style name="TimeDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog">
<item name="android:colorAccent">@color/md_theme_dark_primary</item>
<item name="android:colorPrimary">@color/md_theme_dark_primary</item>
<item name="android:colorPrimaryDark">@color/md_theme_dark_secondary</item>
<!-- <item name="buttonBarPositiveButtonStyle">@style/TextButton</item>-->
<!-- <item name="buttonBarNegativeButtonStyle">@style/TextButton</item>-->
</style>
<style name="TextButton" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
<item name="android:textColor">@color/md_theme_dark_primary</item>
<item name="backgroundTint">@color/md_theme_dark_primary</item>
</style>
</resources> </resources>
+2
View File
@@ -54,6 +54,8 @@
<string name="sheet_schedule_update_timestamp_error_start">The course can\'t begin after it ends!</string> <string name="sheet_schedule_update_timestamp_error_start">The course can\'t begin after it ends!</string>
<string name="sheet_schedule_update_timestamp_error_end">The course can\'t end before it begins!</string> <string name="sheet_schedule_update_timestamp_error_end">The course can\'t end before it begins!</string>
<string name="sheet_schedule_update_text_field_empty_error">This field cannot be empty</string> <string name="sheet_schedule_update_text_field_empty_error">This field cannot be empty</string>
<string name="sheet_schedule_update_time_dialog_start_hint">Event start time</string>
<string name="sheet_schedule_update_time_dialog_end_hint">Event end time</string>
<string name="canteen_no_offer_header">No offers</string> <string name="canteen_no_offer_header">No offers</string>
<string name="canteen_no_offer_desc">There are no offers available for this day</string> <string name="canteen_no_offer_desc">There are no offers available for this day</string>
+15
View File
@@ -80,6 +80,8 @@
<item name="colorOnPrimaryGame">@color/game_light_onPrimary</item> <item name="colorOnPrimaryGame">@color/game_light_onPrimary</item>
<item name="colorContainerGame">@color/game_light_container</item> <item name="colorContainerGame">@color/game_light_container</item>
<item name="colorOnContainerGame">@color/game_light_onContainer</item> <item name="colorOnContainerGame">@color/game_light_onContainer</item>
<item name="materialTimePickerTheme">@style/TimeDialogTheme</item> <!-- TimePicker dialog -->
</style> </style>
<style name="Theme.StudIPTimetable" parent="Base.Theme.StudIPTimetable" /> <style name="Theme.StudIPTimetable" parent="Base.Theme.StudIPTimetable" />
@@ -92,4 +94,17 @@
<item name="checkedIconEnabled">false</item> <item name="checkedIconEnabled">false</item>
<item name="checkedIcon">@null</item> <item name="checkedIcon">@null</item>
</style> </style>
<style name="TimeDialogTheme" parent="ThemeOverlay.MaterialComponents.TimePicker">
<item name="android:colorAccent">@color/md_theme_light_primary</item>
<item name="android:colorPrimary">@color/md_theme_light_primary</item>
<item name="android:colorPrimaryDark">@color/md_theme_light_secondary</item>
<item name="buttonBarPositiveButtonStyle">@style/TextButton</item>
<item name="buttonBarNegativeButtonStyle">@style/TextButton</item>
</style>
<style name="TextButton" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
<item name="android:textColor">@color/md_theme_light_primary</item>
<item name="backgroundTint">@color/md_theme_light_primary</item>
</style>
</resources> </resources>