Benutze ListAdapter statt Kiel für Projects

master
Niko Diamadis 4 years ago
parent d9d78f4f6d
commit 751b304a9b
Signed by: niko
GPG Key ID: BE53B0B17B1B142E

@ -16,8 +16,8 @@ import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.afollestad.materialdialogs.list.uncheckItems
import com.cyb3rko.techniklogger.R
import com.cyb3rko.techniklogger.databinding.FragmentProjectBinding
import com.cyb3rko.techniklogger.recycler.ProjectTechnikerViewHolder
import com.cyb3rko.techniklogger.recycler.ProjectTechnikerViewState
import com.cyb3rko.techniklogger.recycler.ProjectTechniker
import com.cyb3rko.techniklogger.recycler.ProjectTechnikerAdapter
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import com.parse.ParseObject
@ -25,9 +25,6 @@ import com.parse.ParseQuery
import es.dmoral.toasty.Toasty
import java.sql.Time
import java.text.DecimalFormat
import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter
import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter.Companion.adapterOf
import me.ibrahimyilmaz.kiel.core.RecyclerViewHolder
@SuppressLint("SetTextI18n")
class ProjectFragment : Fragment() {
@ -35,13 +32,13 @@ class ProjectFragment : Fragment() {
private lateinit var myContext: Context
private val args: ProjectFragmentArgs by navArgs()
private lateinit var adapter: RecyclerViewAdapter<ProjectTechnikerViewState, RecyclerViewHolder<ProjectTechnikerViewState>>
private lateinit var technikerAdapter: ProjectTechnikerAdapter
private var adminMode = false
private var objectId = ""
private var dauer = ""
private lateinit var einsatz: ParseObject
private lateinit var sharedPref: SharedPreferences
private val techniker: MutableList<ProjectTechnikerViewState.ProjectTechniker> = mutableListOf()
private val techniker: MutableList<ProjectTechniker> = mutableListOf()
private var time = ""
private val binding get() = _binding!!
@ -57,160 +54,148 @@ class ProjectFragment : Fragment() {
objectId = args.objectId
einsatz = ParseObject.createWithoutData("Einsatz", objectId)
adapter = adapterOf {
register(
layoutResource = R.layout.item_recycler_techniker,
viewHolder = ::ProjectTechnikerViewHolder,
onBindBindViewHolder = { vh, _, clickedTechniker ->
vh.textView.text = "${clickedTechniker.name}, ${clickedTechniker.dauer} h"
vh.itemView.setOnClickListener {
if (adminMode || clickedTechniker.name == sharedPref.getString("name", "")) {
MaterialDialog(myContext)
.show {
title(text = clickedTechniker.name)
val uhrzeit = if (clickedTechniker.uhrzeit == "0") time else clickedTechniker.uhrzeit
message(text = Html.fromHtml("<strong><u>Arbeitszeit:</u></strong><br/>$uhrzeit Uhr<br/><br/>Wie möchtest du " +
"diesen Eintrag bearbeiten?"))
positiveButton(text = "Arbeitszeit ändern") {
var tempTime = ""
var time1 = Time(0)
var time2 = Time(0)
val builder = MaterialTimePicker.Builder().setTimeFormat(TimeFormat.CLOCK_24H).setTitleText("Von")
val builder2 = MaterialTimePicker.Builder().setTimeFormat(TimeFormat.CLOCK_24H).setTitleText("Bis")
val picker = builder.build()
val picker2 = builder2.build()
var hour: String
var minute: String
var hoursInMillis: Long
var minutesInMillis: Long
if (clickedTechniker.uhrzeit != "0") {
val times = clickedTechniker.uhrzeit.split(" - ")
builder.setHour(times[0].split(":")[0].toInt())
.setMinute(times[0].split(":")[1].toInt())
builder2.setHour(times[1].split(":")[0].toInt())
.setMinute(times[1].split(":")[1].toInt())
}
picker.addOnPositiveButtonClickListener {
hour = picker.hour.toString()
hour = if (hour.length != 1) hour else "0$hour"
minute = picker.minute.toString()
minute = if (minute.length != 1) minute else "0$minute"
hoursInMillis = picker.hour.toLong() * 3600000
minutesInMillis = picker.minute.toLong() * 60000
time1 = Time(hoursInMillis + minutesInMillis)
val testTime = time.split(" ")[0]
val testHour = testTime.split(":")[0]
val testMinutes = testTime.split(":")[1]
if (testHour > hour) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
} else if (testHour == hour && testMinutes > minute) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
} else {
tempTime += "${hour}:${minute} - "
activity?.let { it1 -> picker2.show(it1.supportFragmentManager, picker2.tag) }
}
}
picker2.addOnPositiveButtonClickListener {
hour = picker2.hour.toString()
hour = if (hour.length != 1) hour else "0$hour"
minute = picker2.minute.toString()
minute = if (minute.length != 1) minute else "0$minute"
hoursInMillis = hour.toLong() * 3600000
minutesInMillis = minute.toLong() * 60000
time2 = Time(hoursInMillis + minutesInMillis)
val testTime = time.split(" ")[2]
val testHour = testTime.split(":")[0]
val testMinutes = testTime.split(":")[1]
if (testHour < hour) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
return@addOnPositiveButtonClickListener
} else if (testHour == hour && testMinutes < minute) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
return@addOnPositiveButtonClickListener
}
tempTime += "${hour}:${minute}"
clickedTechniker.uhrzeit = tempTime
val tempDauer = DecimalFormat("#.#").format((time2.time - time1.time) / 3600 / 1000.toFloat())
clickedTechniker.dauer = tempDauer.replace(",", ".")
technikerAdapter = ProjectTechnikerAdapter {
if (adminMode || it.name == sharedPref.getString("name", "")) {
MaterialDialog(myContext)
.show {
title(text = it.name)
val uhrzeit = if (it.uhrzeit == "0") time else it.uhrzeit
message(text = Html.fromHtml("<strong><u>Arbeitszeit:</u></strong><br/>$uhrzeit Uhr<br/><br/>Wie möchtest du " +
"diesen Eintrag bearbeiten?"))
positiveButton(text = "Arbeitszeit ändern") { _ ->
var tempTime = ""
var time1 = Time(0)
var time2 = Time(0)
val builder = MaterialTimePicker.Builder().setTimeFormat(
TimeFormat.CLOCK_24H).setTitleText("Von")
val builder2 = MaterialTimePicker.Builder().setTimeFormat(TimeFormat.CLOCK_24H).setTitleText("Bis")
val picker = builder.build()
val picker2 = builder2.build()
var hour: String
var minute: String
var hoursInMillis: Long
var minutesInMillis: Long
if (it.uhrzeit != "0") {
val times = it.uhrzeit.split(" - ")
builder.setHour(times[0].split(":")[0].toInt())
.setMinute(times[0].split(":")[1].toInt())
builder2.setHour(times[1].split(":")[0].toInt())
.setMinute(times[1].split(":")[1].toInt())
}
picker.addOnPositiveButtonClickListener {
hour = picker.hour.toString()
hour = if (hour.length != 1) hour else "0$hour"
minute = picker.minute.toString()
minute = if (minute.length != 1) minute else "0$minute"
hoursInMillis = picker.hour.toLong() * 3600000
minutesInMillis = picker.minute.toLong() * 60000
time1 = Time(hoursInMillis + minutesInMillis)
val testTime = time.split(" ")[0]
val testHour = testTime.split(":")[0]
val testMinutes = testTime.split(":")[1]
if (testHour > hour) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
} else if (testHour == hour && testMinutes > minute) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
} else {
tempTime += "${hour}:${minute} - "
activity?.let { it1 -> picker2.show(it1.supportFragmentManager, picker2.tag) }
}
}
picker2.addOnPositiveButtonClickListener { _ ->
hour = picker2.hour.toString()
hour = if (hour.length != 1) hour else "0$hour"
minute = picker2.minute.toString()
minute = if (minute.length != 1) minute else "0$minute"
hoursInMillis = hour.toLong() * 3600000
minutesInMillis = minute.toLong() * 60000
time2 = Time(hoursInMillis + minutesInMillis)
val testTime = time.split(" ")[2]
val testHour = testTime.split(":")[0]
val testMinutes = testTime.split(":")[1]
if (testHour < hour) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
return@addOnPositiveButtonClickListener
} else if (testHour == hour && testMinutes < minute) {
Toasty.warning(myContext, "Zeitpunkt nicht im Zeitraum des Einsatzes", Toasty.LENGTH_LONG).show()
return@addOnPositiveButtonClickListener
}
tempTime += "${hour}:${minute}"
it.uhrzeit = tempTime
val tempDauer = DecimalFormat("#.#").format((time2.time - time1.time) / 3600 / 1000.toFloat())
it.dauer = tempDauer.replace(",", ".")
if (clickedTechniker.teilnahmeKey != "0") {
val dauerFloat = clickedTechniker.dauer.toFloat()
ParseObject.createWithoutData("Teilnahme", clickedTechniker.teilnahmeKey).apply {
put("dauer", dauerFloat)
put("uhrzeit", clickedTechniker.uhrzeit)
saveInBackground()
}
} else {
val query = ParseQuery.getQuery<ParseObject>("Teilnahme")
query.whereEqualTo("von", ParseObject.createWithoutData("Techniker", clickedTechniker.key))
query.whereEqualTo("an", ParseObject.createWithoutData("Einsatz", objectId))
query.getFirstInBackground { obj, e ->
if (e == null) {
clickedTechniker.teilnahmeKey = obj.objectId
val dauerFloat = clickedTechniker.dauer.toFloat()
ParseObject.createWithoutData("Teilnahme", clickedTechniker.teilnahmeKey).apply {
put("dauer", dauerFloat)
put("uhrzeit", clickedTechniker.uhrzeit)
saveInBackground()
}
adapter.notifyDataSetChanged()
binding.recyclerView.scheduleLayoutAnimation()
} else {
Toasty.error(myContext, "Fehler bei Techniker-Abfrage").show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
}
}
}
adapter.notifyDataSetChanged()
binding.recyclerView.scheduleLayoutAnimation()
}
activity?.let { it1 -> picker.show(it1.supportFragmentManager, picker.tag) }
if (it.teilnahmeKey != "0") {
val dauerFloat = it.dauer.toFloat()
ParseObject.createWithoutData("Teilnahme", it.teilnahmeKey).apply {
put("dauer", dauerFloat)
put("uhrzeit", it.uhrzeit)
saveInBackground()
}
negativeButton(text = "Entfernen") {
techniker.remove(clickedTechniker)
if (clickedTechniker.teilnahmeKey != "0") {
ParseObject.createWithoutData ("Teilnahme", clickedTechniker.teilnahmeKey).deleteInBackground() {
adapter.notifyDataSetChanged()
binding.recyclerView.scheduleLayoutAnimation()
binding.technikerView.text = "Techniker: ${techniker.size}"
} else {
val query = ParseQuery.getQuery<ParseObject>("Teilnahme")
query.whereEqualTo("von", ParseObject.createWithoutData("Techniker", it.objectId))
query.whereEqualTo("an", ParseObject.createWithoutData("Einsatz", objectId))
query.getFirstInBackground { obj, e ->
if (e == null) {
it.teilnahmeKey = obj.objectId
val dauerFloat = it.dauer.toFloat()
ParseObject.createWithoutData("Teilnahme", it.teilnahmeKey).apply {
put("dauer", dauerFloat)
put("uhrzeit", it.uhrzeit)
saveInBackground()
}
technikerAdapter.submitList(techniker)
} else {
val query = ParseQuery.getQuery<ParseObject>("Teilnahme")
query.whereEqualTo("von", ParseObject.createWithoutData("Techniker", clickedTechniker.key))
query.whereEqualTo("an", ParseObject.createWithoutData("Einsatz", objectId))
query.getFirstInBackground { obj, e ->
if (e == null) {
obj.deleteInBackground() {
if (it == null) {
adapter.notifyDataSetChanged()
binding.recyclerView.scheduleLayoutAnimation()
binding.technikerView.text = "Techniker: ${techniker.size}"
} else {
Toasty.error(myContext, "Fehler bei Techniker-Löschung").show()
Log.e("TechnikLogger.TechLösch", it.message.toString())
}
}
} else {
Toasty.error(myContext, "Fehler bei Techniker-Abfrage").show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
}
}
Toasty.error(myContext, "Fehler bei Techniker-Abfrage").show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
}
if (techniker.size == 0) showDivider(false)
}
}
technikerAdapter.submitList(techniker)
}
activity?.let { it1 -> picker.show(it1.supportFragmentManager, picker.tag) }
}
negativeButton(text = "Entfernen") { _ ->
techniker.remove(it)
if (it.teilnahmeKey != "0") {
ParseObject.createWithoutData ("Teilnahme", it.teilnahmeKey).deleteInBackground() {
technikerAdapter.submitList(techniker)
binding.technikerView.text = "Techniker: ${techniker.size}"
}
} else {
val query = ParseQuery.getQuery<ParseObject>("Teilnahme")
query.whereEqualTo("von", ParseObject.createWithoutData("Techniker", it.objectId))
query.whereEqualTo("an", ParseObject.createWithoutData("Einsatz", objectId))
query.getFirstInBackground { obj, e ->
if (e == null) {
obj.deleteInBackground {
if (it == null) {
technikerAdapter.submitList(techniker)
binding.technikerView.text = "Techniker: ${techniker.size}"
} else {
Toasty.error(myContext, "Fehler bei Techniker-Löschung").show()
Log.e("TechnikLogger.TechLösch", it.message.toString())
}
}
} else {
Toasty.error(myContext, "Fehler bei Techniker-Abfrage").show()
Log.e("TechnikLogger.TechSuche", e.message.toString())
}
}
}
if (techniker.size == 0) showDivider(false)
}
}
}
)
}
}
loadData()
adapter.submitList(techniker as List<ProjectTechnikerViewState>?)
technikerAdapter.submitList(techniker as List<ProjectTechniker>?)
binding.recyclerView.layoutManager = LinearLayoutManager(myContext)
binding.recyclerView.adapter = adapter
binding.recyclerView.adapter = technikerAdapter
binding.addButton.setOnClickListener {
val name = sharedPref.getString("name", "invalid")!!
@ -235,7 +220,7 @@ class ProjectFragment : Fragment() {
if (e == null) {
ParseObject.deleteAllInBackground(objects)
techniker.clear()
adapter.notifyDataSetChanged()
technikerAdapter.submitList(techniker)
showDivider(false)
binding.technikerView.text = "Techniker: 0"
} else {
@ -249,15 +234,19 @@ class ProjectFragment : Fragment() {
}
}
binding.swipeRefreshLayout.setOnRefreshListener {
binding.titleView.text = ""
binding.dateView.text = ""
binding.locationView.text = ""
techniker.clear()
adapter.notifyDataSetChanged()
showDivider(false)
binding.technikerView.text = "Techniker: 0"
loadData()
binding.swipeRefreshLayout.apply {
setProgressBackgroundColorSchemeResource(R.color.refreshLayoutBackground)
setColorSchemeResources(R.color.refreshLayoutArrow)
setOnRefreshListener {
binding.titleView.text = ""
binding.dateView.text = ""
binding.locationView.text = ""
techniker.clear()
technikerAdapter.submitList(techniker)
showDivider(false)
binding.technikerView.text = "Techniker: 0"
loadData()
}
}
return root
@ -288,17 +277,16 @@ class ProjectFragment : Fragment() {
val dauerEntry = it.getNumber("dauer")!!
val dauer = if (dauerEntry == 0) einsatz.getNumber("dauer")!!.toString() else dauerEntry.toString()
val time = it.getString("uhrzeit")!!
techniker.add(ProjectTechnikerViewState.ProjectTechniker(
techniker.add(ProjectTechniker(
dauer,
teilnehmenderTechniker.getString("name")!!,
teilnehmenderTechniker.objectId,
it.objectId,
dauer,
time
))
}
techniker.sortBy { it.name }
binding.recyclerView.scheduleLayoutAnimation()
adapter.notifyDataSetChanged()
technikerAdapter.submitList(techniker)
binding.technikerView.text = "Techniker: ${techniker.size}"
showDivider()
}
@ -412,14 +400,19 @@ class ProjectFragment : Fragment() {
entryObject.put("von", it)
entryObject.put("an", project)
entryList.add(entryObject)
techniker.add(ProjectTechnikerViewState.ProjectTechniker(it.getString("name")!!, it.objectId, "0", dauer, time))
techniker.add(ProjectTechniker(
dauer,
it.getString("name")!!,
it.objectId,
"0",
time
))
}
ParseObject.saveAllInBackground(entryList) {
if (it == null) {
techniker.sortBy { it.name }
adapter.notifyDataSetChanged()
technikerAdapter.submitList(techniker)
showDivider(true)
binding.recyclerView.scheduleLayoutAnimation()
binding.technikerView.text = "Techniker: ${techniker.size}"
} else {
Toasty.error(myContext, "Fehler bei Techniker-Suche").show()

@ -0,0 +1,9 @@
package com.cyb3rko.techniklogger.recycler
data class ProjectTechniker(
var dauer: String,
val name: String,
val objectId: String,
var teilnahmeKey: String,
var uhrzeit: String
)

@ -0,0 +1,48 @@
package com.cyb3rko.techniklogger.recycler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.cyb3rko.techniklogger.R
class ProjectTechnikerAdapter(
val action: (techniker: ProjectTechniker) -> Unit
) : ListAdapter<ProjectTechniker, ProjectTechnikerAdapter.ViewHolder>(ProjectTechnikerDiffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_recycler_techniker, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val entry = getItem(position)
val title = "${entry.name}, ${entry.dauer} h"
holder.titleView.text = title
holder.titleView.setOnClickListener {
action(entry)
}
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val titleView: TextView = view.findViewById(R.id.title)
}
object ProjectTechnikerDiffCallback : DiffUtil.ItemCallback<ProjectTechniker>() {
override fun areItemsTheSame(oldItem: ProjectTechniker, newItem: ProjectTechniker): Boolean {
return oldItem.objectId == newItem.objectId
}
override fun areContentsTheSame(oldItem: ProjectTechniker, newItem: ProjectTechniker): Boolean {
return oldItem.dauer == newItem.dauer &&
oldItem.name == newItem.name &&
oldItem.teilnahmeKey == newItem.teilnahmeKey &&
oldItem.uhrzeit == newItem.uhrzeit
}
}
}

@ -1,12 +0,0 @@
package com.cyb3rko.techniklogger.recycler
import android.view.View
import android.widget.TextView
import com.cyb3rko.techniklogger.R
import me.ibrahimyilmaz.kiel.core.RecyclerViewHolder
class ProjectTechnikerViewHolder(view: View) : RecyclerViewHolder<ProjectTechnikerViewState.ProjectTechniker>(view) {
val textView: TextView = view.findViewById(R.id.title)
}

@ -1,12 +0,0 @@
package com.cyb3rko.techniklogger.recycler
sealed class ProjectTechnikerViewState {
data class ProjectTechniker(
val name: String,
val key: String,
var teilnahmeKey: String,
var dauer: String,
var uhrzeit: String
) : ProjectTechnikerViewState()
}
Loading…
Cancel
Save