[UI/Attendance] Fix counting issues. Add attendance details dialog.

This commit is contained in:
Kuba Szczodrzyński 2020-05-09 19:18:18 +02:00
parent 65e0e10db6
commit 771712da99
14 changed files with 381 additions and 63 deletions

View File

@ -151,11 +151,17 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
} }
} }
val typeName = types?.get(typeSymbol) ?: "" val typeName = types?.get(typeSymbol) ?: ""
val typeColor = when (typeSymbol) {
"e" -> 0xff673ab7
"en" -> 0xffec407a
"ep" -> 0xff4caf50
else -> null
}?.toInt()
val typeShort = when (baseType) { val typeShort = if (isCounted)
TYPE_UNKNOWN -> typeSymbol data.app.attendanceManager.getTypeShort(baseType)
else -> data.app.attendanceManager.getTypeShort(baseType) else
} typeSymbol
val semester = data.profile?.dateToSemester(lessonDate) ?: 1 val semester = data.profile?.dateToSemester(lessonDate) ?: 1
@ -168,7 +174,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
typeName = typeName, typeName = typeName,
typeShort = typeShort, typeShort = typeShort,
typeSymbol = typeSymbol, typeSymbol = typeSymbol,
typeColor = null, typeColor = typeColor,
date = lessonDate, date = lessonDate,
startTime = startTime, startTime = startTime,
semester = semester, semester = semester,

View File

@ -73,6 +73,6 @@ open class Attendance(
@delegate:Ignore @delegate:Ignore
val typeObject by lazy { val typeObject by lazy {
AttendanceType(profileId, baseType.toLong(), baseType, typeName, typeShort, typeSymbol, typeColor) AttendanceType(profileId, baseType.toLong(), baseType, typeName, typeShort, typeSymbol, typeColor).also { it.isCounted = isCounted }
} }
} }

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.db.entity package pl.szczodrzynski.edziennik.data.db.entity
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Ignore
@Entity(tableName = "attendanceTypes", @Entity(tableName = "attendanceTypes",
primaryKeys = ["profileId", "id"]) primaryKeys = ["profileId", "id"])
@ -23,6 +24,9 @@ data class AttendanceType (
val typeColor: Int? val typeColor: Int?
) : Comparable<AttendanceType> { ) : Comparable<AttendanceType> {
@Ignore
var isCounted: Boolean = true
// attendance bar order: // attendance bar order:
// day_free, present, present_custom, unknown, belated_excused, belated, released, absent_excused, absent, // day_free, present, present_custom, unknown, belated_excused, belated, released, absent_excused, absent,
override fun compareTo(other: AttendanceType): Int { override fun compareTo(other: AttendanceType): Int {

View File

@ -12,6 +12,7 @@ import android.util.AttributeSet
import android.view.View import android.view.View
import pl.szczodrzynski.edziennik.dp import pl.szczodrzynski.edziennik.dp
import pl.szczodrzynski.edziennik.utils.Colors import pl.szczodrzynski.edziennik.utils.Colors
import kotlin.math.roundToInt
/* https://github.com/JakubekWeg/Mobishit/blob/master/app/src/main/java/jakubweg/mobishit/view/AttendanceBarView.kt */ /* https://github.com/JakubekWeg/Mobishit/blob/master/app/src/main/java/jakubweg/mobishit/view/AttendanceBarView.kt */
class AttendanceBar : View { class AttendanceBar : View {
@ -34,7 +35,7 @@ class AttendanceBar : View {
mCornerRadius = 4.dp.toFloat() mCornerRadius = 4.dp.toFloat()
if (isInEditMode) if (isInEditMode)
setAttendanceData(mapOf( setAttendanceData(listOf(
0xff43a047.toInt() to 23, 0xff43a047.toInt() to 23,
0xff009688.toInt() to 187, 0xff009688.toInt() to 187,
0xff3f51b5.toInt() to 46, 0xff3f51b5.toInt() to 46,
@ -49,8 +50,8 @@ class AttendanceBar : View {
// color, count // color, count
private class AttendanceItem(var color: Int, var count: Int) private class AttendanceItem(var color: Int, var count: Int)
fun setAttendanceData(list: Map<Int, Int>) { fun setAttendanceData(list: List<Pair<Int, Int>>) {
attendancesList = list.map { AttendanceItem(it.key, it.value) } attendancesList = list.map { AttendanceItem(it.first, it.second) }
setWillNotDraw(false) setWillNotDraw(false)
invalidate() invalidate()
} }
@ -91,11 +92,12 @@ class AttendanceBar : View {
mainPaint.color = e.color mainPaint.color = e.color
canvas.drawRect(left, top, left + width, bottom, mainPaint) canvas.drawRect(left, top, left + width, bottom, mainPaint)
val percentage = (100f * e.count / sum).roundToInt().toString() + "%"
val textBounds = Rect() val textBounds = Rect()
textPaint.getTextBounds(e.count.toString(), 0, e.count.toString().length, textBounds) textPaint.getTextBounds(percentage, 0, percentage.length, textBounds)
if (width > textBounds.width() + 8.dp && height > textBounds.height() + 2.dp) { if (width > textBounds.width() + 8.dp && height > textBounds.height() + 2.dp) {
textPaint.color = Colors.legibleTextColor(e.color) textPaint.color = Colors.legibleTextColor(e.color)
canvas.drawText(e.count.toString(), left + width / 2, bottom - height / 2 + textBounds.height()/2, textPaint) canvas.drawText(percentage, left + width / 2, bottom - height / 2 + textBounds.height()/2, textPaint)
} }
left += width left += width

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-5-9.
*/
package pl.szczodrzynski.edziennik.ui.modules.attendance
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.ColorUtils
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.databinding.AttendanceDetailsDialogBinding
import pl.szczodrzynski.edziennik.setTintColor
import kotlin.coroutines.CoroutineContext
class AttendanceDetailsDialog(
val activity: AppCompatActivity,
val attendance: AttendanceFull,
val onShowListener: ((tag: String) -> Unit)? = null,
val onDismissListener: ((tag: String) -> Unit)? = null
) : CoroutineScope {
companion object {
private const val TAG = "AttendanceDetailsDialog"
}
private lateinit var app: App
private lateinit var b: AttendanceDetailsDialogBinding
private lateinit var dialog: AlertDialog
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
// local variables go here
init { run {
if (activity.isFinishing)
return@run
onShowListener?.invoke(TAG)
app = activity.applicationContext as App
b = AttendanceDetailsDialogBinding.inflate(activity.layoutInflater)
dialog = MaterialAlertDialogBuilder(activity)
.setView(b.root)
.setPositiveButton(R.string.close, null)
.setOnDismissListener {
onDismissListener?.invoke(TAG)
}
.show()
val manager = app.attendanceManager
val attendanceColor = manager.getAttendanceColor(attendance)
b.attendance = attendance
b.devMode = App.debugMode
b.attendanceName.setTextColor(if (ColorUtils.calculateLuminance(attendanceColor) > 0.3) 0xaa000000.toInt() else 0xccffffff.toInt())
b.attendanceName.background.setTintColor(attendanceColor)
b.attendanceIsCounted.setText(if (attendance.isCounted) R.string.yes else R.string.no)
}}
}

View File

@ -95,7 +95,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
}}) }})
adapter.onAttendanceClick = { adapter.onAttendanceClick = {
//GradeDetailsDialog(activity, it) AttendanceDetailsDialog(activity, it)
} }
}; return true} }; return true}
@ -174,15 +174,14 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
items.forEach { month -> items.forEach { month ->
month.typeCountMap = month.items month.typeCountMap = month.items
.groupBy { it.typeObject } .groupBy { it.typeObject }
.map { it.key to it.value.count { a -> a.isCounted } } .map { it.key to it.value.size }
.sortedBy { it.first } .sortedBy { it.first }
.toMap() .toMap()
val totalCount = month.typeCountMap.entries.sumBy { val totalCount = month.typeCountMap.entries.sumBy {
when (it.key.baseType) { if (!it.key.isCounted || it.key.baseType == Attendance.TYPE_UNKNOWN)
Attendance.TYPE_UNKNOWN -> 0 0
else -> it.value else it.value
}
} }
val presenceCount = month.typeCountMap.entries.sumBy { val presenceCount = month.typeCountMap.entries.sumBy {
when (it.key.baseType) { when (it.key.baseType) {
@ -190,7 +189,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
Attendance.TYPE_PRESENT_CUSTOM, Attendance.TYPE_PRESENT_CUSTOM,
Attendance.TYPE_BELATED, Attendance.TYPE_BELATED,
Attendance.TYPE_BELATED_EXCUSED, Attendance.TYPE_BELATED_EXCUSED,
Attendance.TYPE_RELEASED -> it.value Attendance.TYPE_RELEASED -> if (it.key.isCounted) it.value else 0
else -> 0 else -> 0
} }
} }
@ -213,6 +212,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
type = it.key, type = it.key,
items = it.value.toMutableList() items = it.value.toMutableList()
) } ) }
.sortedBy { it.items.size }
items.forEach { type -> items.forEach { type ->
type.percentage = if (attendance.isEmpty()) type.percentage = if (attendance.isEmpty())

View File

@ -76,7 +76,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
if (adapter.items.isNotNullNorEmpty() && b.list.adapter == null) { if (adapter.items.isNotNullNorEmpty() && b.list.adapter == null) {
b.list.adapter = adapter b.list.adapter = adapter
b.list.apply { b.list.apply {
setHasFixedSize(true) setHasFixedSize(false)
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
isNestedScrollingEnabled = false isNestedScrollingEnabled = false
} }
@ -103,7 +103,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
}}) }})
adapter.onAttendanceClick = { adapter.onAttendanceClick = {
//GradeDetailsDialog(activity, it) AttendanceDetailsDialog(activity, it)
} }
b.toggleGroup.check(when (periodSelection) { b.toggleGroup.check(when (periodSelection) {
@ -184,15 +184,14 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
items.forEach { subject -> items.forEach { subject ->
subject.typeCountMap = subject.items subject.typeCountMap = subject.items
.groupBy { it.typeObject } .groupBy { it.typeObject }
.map { it.key to it.value.count { a -> a.isCounted } } .map { it.key to it.value.size }
.sortedBy { it.first } .sortedBy { it.first }
.toMap() .toMap()
val totalCount = subject.typeCountMap.entries.sumBy { val totalCount = subject.typeCountMap.entries.sumBy {
when (it.key.baseType) { if (!it.key.isCounted || it.key.baseType == Attendance.TYPE_UNKNOWN)
Attendance.TYPE_UNKNOWN -> 0 0
else -> it.value else it.value
}
} }
val presenceCount = subject.typeCountMap.entries.sumBy { val presenceCount = subject.typeCountMap.entries.sumBy {
when (it.key.baseType) { when (it.key.baseType) {
@ -200,7 +199,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
Attendance.TYPE_PRESENT_CUSTOM, Attendance.TYPE_PRESENT_CUSTOM,
Attendance.TYPE_BELATED, Attendance.TYPE_BELATED,
Attendance.TYPE_BELATED_EXCUSED, Attendance.TYPE_BELATED_EXCUSED,
Attendance.TYPE_RELEASED -> it.value Attendance.TYPE_RELEASED -> if (it.key.isCounted) it.value else 0
else -> 0 else -> 0
} }
} }
@ -218,7 +217,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
val typeCountMap = attendance val typeCountMap = attendance
.groupBy { it.typeObject } .groupBy { it.typeObject }
.map { it.key to it.value.count { a -> a.isCounted } } .map { it.key to it.value.size }
.sortedBy { it.first } .sortedBy { it.first }
.toMap() .toMap()
@ -228,11 +227,11 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
presenceCountSum.toFloat() / totalCountSum.toFloat() * 100f presenceCountSum.toFloat() / totalCountSum.toFloat() * 100f
launch { launch {
b.attendanceBar.setAttendanceData(typeCountMap.mapKeys { manager.getAttendanceColor(it.key) }) b.attendanceBar.setAttendanceData(typeCountMap.map { manager.getAttendanceColor(it.key) to it.value })
b.attendanceBar.isInvisible = typeCountMap.isEmpty() b.attendanceBar.isInvisible = typeCountMap.isEmpty()
b.previewContainer.removeAllViews() b.previewContainer.removeAllViews()
val sum = typeCountMap.entries.sumBy { it.value }.toFloat() //val sum = typeCountMap.entries.sumBy { it.value }.toFloat()
typeCountMap.forEach { (type, count) -> typeCountMap.forEach { (type, count) ->
val layout = LinearLayout(activity) val layout = LinearLayout(activity)
val attendanceObject = Attendance( val attendanceObject = Attendance(
@ -252,7 +251,8 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
) )
layout.addView(AttendanceView(activity, attendanceObject, manager)) layout.addView(AttendanceView(activity, attendanceObject, manager))
layout.addView(TextView(activity).also { layout.addView(TextView(activity).also {
it.setText(R.string.attendance_percentage_format, count/sum*100f) //it.setText(R.string.attendance_percentage_format, count/sum*100f)
it.text = count.toString()
it.setPadding(0, 0, 5.dp, 0) it.setPadding(0, 0, 5.dp, 0)
}) })
layout.setPadding(0, 8.dp, 0, 8.dp) layout.setPadding(0, 8.dp, 0, 8.dp)

View File

@ -49,7 +49,7 @@ class MonthViewHolder(
b.unread.isVisible = item.hasUnseen b.unread.isVisible = item.hasUnseen
b.attendanceBar.setAttendanceData(item.typeCountMap.mapKeys { manager.getAttendanceColor(it.key) }) b.attendanceBar.setAttendanceData(item.typeCountMap.map { manager.getAttendanceColor(it.key) to it.value })
b.previewContainer.isInvisible = item.state != STATE_CLOSED b.previewContainer.isInvisible = item.state != STATE_CLOSED
b.summaryContainer.isInvisible = item.state == STATE_CLOSED b.summaryContainer.isInvisible = item.state == STATE_CLOSED
@ -77,7 +77,8 @@ class MonthViewHolder(
) )
layout.addView(AttendanceView(contextWrapper, attendance, manager)) layout.addView(AttendanceView(contextWrapper, attendance, manager))
layout.addView(TextView(contextWrapper).also { layout.addView(TextView(contextWrapper).also {
it.setText(R.string.attendance_percentage_format, count/sum*100f) //it.setText(R.string.attendance_percentage_format, count/sum*100f)
it.text = count.toString()
it.setPadding(0, 0, 5.dp, 0) it.setPadding(0, 0, 5.dp, 0)
}) })
layout.setPadding(0, 8.dp, 0, 0) layout.setPadding(0, 8.dp, 0, 0)

View File

@ -42,7 +42,7 @@ class SubjectViewHolder(
b.unread.isVisible = item.hasUnseen b.unread.isVisible = item.hasUnseen
b.attendanceBar.setAttendanceData(item.typeCountMap.mapKeys { manager.getAttendanceColor(it.key) }) b.attendanceBar.setAttendanceData(item.typeCountMap.map { manager.getAttendanceColor(it.key) to it.value })
b.percentage.isVisible = true b.percentage.isVisible = true

View File

@ -5,13 +5,14 @@
package pl.szczodrzynski.edziennik.ui.modules.attendance.viewholder package pl.szczodrzynski.edziennik.ui.modules.attendance.viewholder
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.concat
import pl.szczodrzynski.edziennik.data.db.entity.Attendance import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.databinding.AttendanceItemTypeBinding import pl.szczodrzynski.edziennik.databinding.AttendanceItemTypeBinding
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
@ -43,7 +44,11 @@ class TypeViewHolder(
b.unread.isVisible = item.hasUnseen b.unread.isVisible = item.hasUnseen
b.previewContainer.visibility = if (item.state == AttendanceAdapter.STATE_CLOSED) View.VISIBLE else View.INVISIBLE b.details.text = listOf(
app.getString(R.string.attendance_percentage_format, item.percentage),
app.getString(R.string.attendance_type_yearly_format, item.items.size),
app.getString(R.string.attendance_type_semester_format, item.semesterCount)
).concat("")
b.type.setAttendance(Attendance( b.type.setAttendance(Attendance(
profileId = 0, profileId = 0,

View File

@ -51,16 +51,16 @@ class AttendanceManager(val app: App) : CoroutineScope {
} }
} }
fun getAttendanceColor(typeObject: AttendanceType): Int { fun getAttendanceColor(typeObject: AttendanceType): Int {
return (if (useSymbols) typeObject.typeColor else null) ?: when (typeObject.baseType) { return (if (useSymbols) typeObject.typeColor else null)
Attendance.TYPE_PRESENT_CUSTOM -> typeObject.typeColor ?: 0xff64b5f6.toInt() ?: if (typeObject.baseType == Attendance.TYPE_PRESENT_CUSTOM || !typeObject.isCounted)
else -> getAttendanceColor(typeObject.baseType) typeObject.typeColor ?: 0xff64b5f6.toInt()
} else getAttendanceColor(typeObject.baseType)
} }
fun getAttendanceColor(attendance: Attendance): Int { fun getAttendanceColor(attendance: Attendance): Int {
return (if (useSymbols) attendance.typeColor else null) ?: when (attendance.baseType) { return (if (useSymbols) attendance.typeColor else null)
Attendance.TYPE_PRESENT_CUSTOM -> attendance.typeColor ?: 0xff64b5f6.toInt() ?: if (attendance.baseType == Attendance.TYPE_PRESENT_CUSTOM || !attendance.isCounted)
else -> getAttendanceColor(attendance.baseType) attendance.typeColor ?: 0xff64b5f6.toInt()
} else getAttendanceColor(attendance.baseType)
} }
/* _ _ _____ _____ _ __ _ /* _ _ _____ _____ _ __ _

View File

@ -0,0 +1,235 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Kuba Szczodrzyński 2020-5-9.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<import type="pl.szczodrzynski.edziennik.utils.Utils"/>
<import type="pl.szczodrzynski.edziennik.utils.models.Date"/>
<import type="pl.szczodrzynski.edziennik.utils.models.Time"/>
<variable
name="attendance"
type="pl.szczodrzynski.edziennik.data.db.full.AttendanceFull" />
<variable
name="devMode"
type="boolean" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="24dp"
android:paddingTop="24dp"
android:paddingRight="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/attendanceName"
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_rounded_16dp"
android:gravity="center"
android:padding="8dp"
android:text="@{attendance.typeShort}"
android:textIsSelectable="true"
android:textSize="36sp"
app:autoSizeMinTextSize="18sp"
app:autoSizeMaxTextSize="56sp"
app:autoSizeTextType="uniform"
tools:background="#ff673ab7"
tools:text="e" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{@string/dialog_grade_details_semester_format(attendance.semester)}"
android:textAppearance="@style/NavView.TextView.Helper"
android:textIsSelectable="true"
tools:text="semestr 1" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{attendance.subjectLongName}"
android:textAppearance="@style/NavView.TextView.Title"
android:textIsSelectable="true"
tools:text="matematyka" />
</LinearLayout>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/attendance_details_teacher"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{attendance.teacherName}"
android:textIsSelectable="true"
tools:text="Andrzej Religijny" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_type"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{attendance.typeName}"
android:textIsSelectable="true"
tools:text="nieobecność nieusprawiedliwiona" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_date"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{attendance.date.formattedString}"
android:textIsSelectable="true"
tools:text="30 lutego 2002" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_time"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{attendance.startTime.stringHM}"
android:textIsSelectable="true"
tools:text="10:60" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_lesson_topic"
android:textAppearance="@style/NavView.TextView.Helper"
android:visibility="@{attendance.lessonTopic == null ? View.GONE : View.VISIBLE}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{attendance.lessonTopic}"
android:textIsSelectable="true"
android:visibility="@{attendance.lessonTopic == null ? View.GONE : View.VISIBLE}"
tools:text="Malowanie autoportretu na ścianie sali gimnastycznej. Modlitwa w terenie." />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_is_counted"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:id="@+id/attendanceIsCounted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textIsSelectable="true"
tools:text="Tak" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:visibility="@{devMode ? View.VISIBLE : View.GONE}">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_id"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{Long.toString(attendance.id)}"
android:textIsSelectable="true"
tools:text="12345" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/attendance_details_type_id"
android:textAppearance="@style/NavView.TextView.Helper" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{Long.toString(attendance.baseType)}"
android:textIsSelectable="true"
tools:text="12345" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</layout>

View File

@ -27,7 +27,7 @@
android:orientation="horizontal"> android:orientation="horizontal">
<LinearLayout <LinearLayout
android:layout_width="32dp" android:layout_width="48dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_horizontal"> android:gravity="center_horizontal">
@ -81,26 +81,17 @@
tools:background="@android:drawable/ic_menu_more" /> tools:background="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginBottom="8dp">
<TextView <TextView
android:id="@+id/previewContainer" android:id="@+id/details"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp" android:layout_marginHorizontal="8dp"
android:layout_marginRight="8dp" android:layout_marginBottom="8dp"
android:textAppearance="@style/NavView.TextView.Helper"
android:textSize="14sp" android:textSize="14sp"
android:visibility="gone"
tools:text="57,67% • 521 przez cały rok • 134 w tym semestrze" tools:text="57,67% • 521 przez cały rok • 134 w tym semestrze"
tools:text1="Cały rok: 3 oceny • suma: 320 pkt" tools:text1="Cały rok: 3 oceny • suma: 320 pkt"
tools:text2="Cały rok: 15 ocen • średnia: 2,62" tools:text2="Cały rok: 15 ocen • średnia: 2,62" />
tools:visibility="visible" />
</FrameLayout>
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@ -1305,4 +1305,14 @@
<string name="you_are_offline_text">Jesteś offline. Spróbuj włączyć Wi-Fi lub dane komórkowe.</string> <string name="you_are_offline_text">Jesteś offline. Spróbuj włączyć Wi-Fi lub dane komórkowe.</string>
<string name="you_are_offline_title">Połączenie sieciowe</string> <string name="you_are_offline_title">Połączenie sieciowe</string>
<string name="attendance_tab_types">Wg typu</string> <string name="attendance_tab_types">Wg typu</string>
<string name="attendance_type_yearly_format">%d przez cały rok</string>
<string name="attendance_type_semester_format">%d w tym semestrze</string>
<string name="attendance_details_teacher">Nauczyciel</string>
<string name="attendance_details_type">Rodzaj</string>
<string name="attendance_details_date">Data</string>
<string name="attendance_details_time">Godzina</string>
<string name="attendance_details_lesson_topic">Temat lekcji</string>
<string name="attendance_details_is_counted">Liczona do puli?</string>
<string name="attendance_details_id">ID frekwencji</string>
<string name="attendance_details_type_id">ID rodzaju podstawowego</string>
</resources> </resources>