Archived
Replaced custom TimePickerFragment.kt with standard MaterialTimePicker
This commit is contained in:
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user