Compare commits

..

2 Commits

32 changed files with 241 additions and 295 deletions

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DeviceTable">
<option name="columnSorters">
<list>
<ColumnSorterState>
<option name="column" value="Name" />
<option name="order" value="ASCENDING" />
</ColumnSorterState>
</list>
</option>
</component>
</project>

View File

@ -13,11 +13,12 @@ import android.widget.ProgressBar
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.dano.test1.auth.LoginManager
import com.dano.test1.auth.TokenStore
import com.dano.test1.network.DatabaseDownloader import com.dano.test1.network.DatabaseDownloader
import com.dano.test1.network.LoginManager
import com.dano.test1.network.TokenStore
import com.dano.test1.questionnaire.QuestionnaireBase import com.dano.test1.questionnaire.QuestionnaireBase
import com.dano.test1.ui.HandlerOpeningScreen import com.dano.test1.ui.HandlerOpeningScreen
import com.dano.test1.util.LanguageManager
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {

View File

@ -1,4 +1,4 @@
package com.dano.test1.network package com.dano.test1.auth
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Context import android.content.Context

View File

@ -1,4 +1,4 @@
package com.dano.test1.network package com.dano.test1.auth
import android.content.Context import android.content.Context

View File

@ -1,4 +1,4 @@
package com.dano.test1.data package com.dano.test1.export
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
@ -7,7 +7,7 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
import android.provider.MediaStore import android.provider.MediaStore
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.MyApp import com.dano.test1.MyApp
import org.apache.poi.ss.usermodel.Row import org.apache.poi.ss.usermodel.Row
import org.apache.poi.xssf.usermodel.XSSFWorkbook import org.apache.poi.xssf.usermodel.XSSFWorkbook
@ -41,8 +41,8 @@ class ExcelExportService(
val orderedIds = headerRepo.loadOrderedIds() val orderedIds = headerRepo.loadOrderedIds()
if (orderedIds.isEmpty()) return null if (orderedIds.isEmpty()) return null
val clients = MyApp.database.clientDao().getAllClients() val clients = MyApp.Companion.database.clientDao().getAllClients()
val questionnaires = MyApp.database.questionnaireDao().getAll() val questionnaires = MyApp.Companion.database.questionnaireDao().getAll()
val questionnaireIdSet = questionnaires.map { it.id }.toSet() val questionnaireIdSet = questionnaires.map { it.id }.toSet()
val wb = XSSFWorkbook() val wb = XSSFWorkbook()
@ -71,9 +71,9 @@ class ExcelExportService(
var c = 0 var c = 0
row.createCell(c++).setCellValue((rowIdx + 1).toDouble()) row.createCell(c++).setCellValue((rowIdx + 1).toDouble())
val completedForClient = MyApp.database.completedQuestionnaireDao().getAllForClient(client.clientCode) val completedForClient = MyApp.Companion.database.completedQuestionnaireDao().getAllForClient(client.clientCode)
val statusMap = completedForClient.associate { it.questionnaireId to it.isDone } val statusMap = completedForClient.associate { it.questionnaireId to it.isDone }
val answers = MyApp.database.answerDao().getAnswersForClient(client.clientCode) val answers = MyApp.Companion.database.answerDao().getAnswersForClient(client.clientCode)
val answerMap = answers.associate { it.questionId to it.answerValue } val answerMap = answers.associate { it.questionId to it.answerValue }
orderedIds.forEach { id -> orderedIds.forEach { id ->
@ -179,4 +179,4 @@ class ExcelExportService(
for (key in candidates) localizeEnglishNoBrackets(key)?.let { return it } for (key in candidates) localizeEnglishNoBrackets(key)?.let { return it }
return raw return raw
} }
} }

View File

@ -1,9 +1,9 @@
package com.dano.test1.data package com.dano.test1.export
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import org.apache.poi.ss.usermodel.CellType import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.ss.usermodel.DateUtil import org.apache.poi.ss.usermodel.DateUtil
import org.apache.poi.xssf.usermodel.XSSFWorkbook import org.apache.poi.xssf.usermodel.XSSFWorkbook

View File

@ -1,4 +1,4 @@
package com.dano.test1 package com.dano.test1.network
import java.io.File import java.io.File
import java.security.SecureRandom import java.security.SecureRandom
@ -68,4 +68,4 @@ object AES256Helper {
cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv)) cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv))
return cipher.doFinal(ct) return cipher.doFinal(ct)
} }
} }

View File

@ -2,7 +2,6 @@ package com.dano.test1.network
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import com.dano.test1.AES256Helper
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@ -8,7 +8,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import android.database.Cursor import android.database.Cursor
import com.dano.test1.AES256Helper
import okhttp3.* import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.asRequestBody

View File

@ -1,15 +1,12 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.util.LanguageManager
import com.dano.test1.LanguageManager import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.network.TokenStore import com.dano.test1.auth.TokenStore
import com.dano.test1.utils.ViewUtils
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -44,10 +41,10 @@ class HandlerClientCoachCode(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: "" questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
ViewUtils.setTextSizePercentOfScreenHeight(titleTextView, 0.03f) titleTextView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f) questionTextView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(clientCodeField, 0.025f) clientCodeField.setTextSizePercentOfScreenHeight(0.025f)
ViewUtils.setTextSizePercentOfScreenHeight(coachCodeField, 0.025f) coachCodeField.setTextSizePercentOfScreenHeight(0.025f)
// Client-Code: nur verwenden, wenn bereits geladen // Client-Code: nur verwenden, wenn bereits geladen
val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE
@ -63,7 +60,7 @@ class HandlerClientCoachCode(
val coachFromLogin = TokenStore.getUsername(layout.context) val coachFromLogin = TokenStore.getUsername(layout.context)
if (!coachFromLogin.isNullOrBlank()) { if (!coachFromLogin.isNullOrBlank()) {
coachCodeField.setText(coachFromLogin) coachCodeField.setText(coachFromLogin)
ViewUtils.lockEditField(coachCodeField) // optisch & technisch gesperrt lockCoachField(coachCodeField) // optisch & technisch gesperrt
} else { } else {
// Falls (theoretisch) kein Login-Username vorhanden ist, verhalten wie bisher // Falls (theoretisch) kein Login-Username vorhanden ist, verhalten wie bisher
coachCodeField.setText(answers["coach_code"] as? String ?: "") coachCodeField.setText(answers["coach_code"] as? String ?: "")
@ -96,7 +93,7 @@ class HandlerClientCoachCode(
val dbExistedBefore = dbPath.exists() val dbExistedBefore = dbPath.exists()
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
val existingClient = MyApp.database.clientDao().getClientByCode(clientCode) val existingClient = MyApp.Companion.database.clientDao().getClientByCode(clientCode)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if (existingClient != null && clientCodeField.isEnabled) { if (existingClient != null && clientCodeField.isEnabled) {
@ -107,7 +104,7 @@ class HandlerClientCoachCode(
goToNextQuestion() goToNextQuestion()
if (!dbExistedBefore) { if (!dbExistedBefore) {
MyApp.database.close() MyApp.Companion.database.close()
dbPath.delete() dbPath.delete()
val journalFile = layout.context.getDatabasePath("questionnaire_database-journal") val journalFile = layout.context.getDatabasePath("questionnaire_database-journal")
journalFile.delete() journalFile.delete()
@ -142,4 +139,19 @@ class HandlerClientCoachCode(
// Not used // Not used
} }
private fun lockCoachField(field: EditText) {
field.isFocusable = false
field.isFocusableInTouchMode = false
field.isCursorVisible = false
field.keyListener = null
field.isLongClickable = false
field.isClickable = false
field.setBackgroundResource(R.drawable.bg_field_locked)
field.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_24, 0)
field.compoundDrawablePadding = dp(8)
field.alpha = 0.95f
}
private fun dp(v: Int): Int =
(v * layout.resources.displayMetrics.density).toInt()
} }

View File

@ -1,10 +1,8 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
/* /*

View File

@ -1,4 +1,4 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.content.Context import android.content.Context
import android.view.View import android.view.View
@ -6,16 +6,13 @@ import android.widget.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.util.LanguageManager
import com.dano.test1.LanguageManager import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.questionnaire.MAX_VALUE_YEAR import com.dano.test1.util.setupSpinner
import com.dano.test1.ui.Month import com.dano.test1.util.Month
import com.dano.test1.ui.Months import com.dano.test1.util.Months
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils
/* /*
Zweck: Zweck:
@ -57,12 +54,11 @@ class HandlerDateSpinner(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: "" questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: "" textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
// Schriftgrößen pro Bildschirmhöhe textView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(textView, 0.03f) questionTextView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f) labelDay.setTextSizePercentOfScreenHeight(0.025f)
ViewUtils.setTextSizePercentOfScreenHeight(labelDay, 0.025f) labelMonth.setTextSizePercentOfScreenHeight(0.025f)
ViewUtils.setTextSizePercentOfScreenHeight(labelMonth, 0.025f) labelYear.setTextSizePercentOfScreenHeight(0.025f)
ViewUtils.setTextSizePercentOfScreenHeight(labelYear, 0.025f)
// gespeicherte Antwort (YYYY-MM-DD) lesen // gespeicherte Antwort (YYYY-MM-DD) lesen
val (savedYear, savedMonthIndex, savedDay) = question.question?.let { val (savedYear, savedMonthIndex, savedDay) = question.question?.let {
@ -79,10 +75,9 @@ class HandlerDateSpinner(
?: months[today.get(Calendar.MONTH)] ?: months[today.get(Calendar.MONTH)]
val defaultYear = savedYear ?: today.get(Calendar.YEAR) val defaultYear = savedYear ?: today.get(Calendar.YEAR)
// Spinner responsiv aufsetzen (Schrift + Zeilenhöhe ohne Abschneiden) spinnerDay.setupSpinner(days, defaultDay)
ViewUtils.setupResponsiveSpinner(context, spinnerDay, days, defaultDay) spinnerMonth.setupSpinner(months, defaultMonth)
ViewUtils.setupResponsiveSpinner(context, spinnerMonth, months, defaultMonth) spinnerYear.setupSpinner(years, defaultYear)
ViewUtils.setupResponsiveSpinner(context, spinnerYear, years, defaultYear)
// DB-Abfrage, falls noch nicht im answers-Map // DB-Abfrage, falls noch nicht im answers-Map
val answerMapKey = question.question ?: (question.id ?: "") val answerMapKey = question.question ?: (question.id ?: "")
@ -92,7 +87,7 @@ class HandlerDateSpinner(
val clientCode = GlobalValues.LAST_CLIENT_CODE val clientCode = GlobalValues.LAST_CLIENT_CODE
if (clientCode.isNullOrBlank()) return@launch if (clientCode.isNullOrBlank()) return@launch
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) val allAnswersForClient = MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
val myQuestionId = questionnaireMeta + "-" + question.question val myQuestionId = questionnaireMeta + "-" + question.question
val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue

View File

@ -1,16 +1,14 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.content.Context import android.content.Context
import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.util.LanguageManager
import com.dano.test1.LanguageManager import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils
import kotlinx.coroutines.* import kotlinx.coroutines.*
/* /*
@ -72,8 +70,8 @@ class HandlerGlassScaleQuestion(
titleTv.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: "" titleTv.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
questionTv.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: "" questionTv.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
ViewUtils.setTextSizePercentOfScreenHeight(titleTv, 0.03f) titleTv.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTv, 0.03f) questionTv.setTextSizePercentOfScreenHeight(0.03f)
// Header Icons // Header Icons
val header = layout.findViewById<LinearLayout>(R.id.glass_header) val header = layout.findViewById<LinearLayout>(R.id.glass_header)
@ -107,7 +105,7 @@ class HandlerGlassScaleQuestion(
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
try { try {
val clientCode = GlobalValues.LAST_CLIENT_CODE ?: return@launch val clientCode = GlobalValues.LAST_CLIENT_CODE ?: return@launch
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) val allAnswersForClient = MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
val answerMap = allAnswersForClient.associateBy({ it.questionId }, { it.answerValue }) val answerMap = allAnswersForClient.associateBy({ it.questionId }, { it.answerValue })
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@ -155,7 +153,7 @@ class HandlerGlassScaleQuestion(
text = LanguageManager.getText(languageID, symptomKey) text = LanguageManager.getText(languageID, symptomKey)
layoutParams = TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 4f) layoutParams = TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 4f)
setPadding(4, 16, 4, 16) setPadding(4, 16, 4, 16)
ViewUtils.setTextSizePercentOfScreenHeight(this, 0.022f) setTextSizePercentOfScreenHeight(0.022f)
} }
row.addView(symptomText) row.addView(symptomText)

View File

@ -1,18 +1,15 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import android.text.Html import android.text.Html
import androidx.core.widget.TextViewCompat
import kotlinx.coroutines.* import kotlinx.coroutines.*
import com.dano.test1.questionnaire.GlobalValues import android.util.TypedValue
import com.dano.test1.LanguageManager import androidx.core.widget.TextViewCompat
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
/* /*
@ -63,9 +60,8 @@ class HandlerLastPage(
finishBtn.isAllCaps = false finishBtn.isAllCaps = false
applyResponsiveTextSizing(finishBtn) applyResponsiveTextSizing(finishBtn)
// Überschriften responsiv skalieren (wie zuvor) titleTv.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(titleTv, 0.03f) questionTv.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTv, 0.03f)
// Buttons // Buttons
prevBtn.setOnClickListener { goToPreviousQuestion() } prevBtn.setOnClickListener { goToPreviousQuestion() }

View File

@ -1,18 +1,15 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.content.Context import android.content.Context
import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import androidx.core.widget.TextViewCompat
import kotlinx.coroutines.* import kotlinx.coroutines.*
import com.dano.test1.questionnaire.GlobalValues import android.util.TypedValue
import com.dano.test1.LanguageManager import androidx.core.widget.TextViewCompat
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils
/* /*
Zweck: Zweck:
@ -44,9 +41,8 @@ class HandlerMultiCheckboxQuestion(
questionTextView.text = this.question.textKey?.let { LanguageManager.getText(languageID, it) } ?: "" questionTextView.text = this.question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
questionTitle.text = this.question.question?.let { LanguageManager.getText(languageID, it) } ?: "" questionTitle.text = this.question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
// Textgrößen pro Bildschirmhöhe (wie bei deinen anderen Handlern) questionTextView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f) questionTitle.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTitle, 0.03f)
container.removeAllViews() container.removeAllViews()
@ -95,7 +91,7 @@ class HandlerMultiCheckboxQuestion(
val clientCode = GlobalValues.LAST_CLIENT_CODE val clientCode = GlobalValues.LAST_CLIENT_CODE
if (clientCode.isNullOrBlank()) return@launch if (clientCode.isNullOrBlank()) return@launch
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) val allAnswersForClient = MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
val myQuestionId = questionnaireMeta + "-" + question.question val myQuestionId = questionnaireMeta + "-" + question.question
val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue

View File

@ -1,17 +1,14 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import android.text.Html import android.text.Html
import android.widget.* import android.widget.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.util.LanguageManager
import com.dano.test1.LanguageManager import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils
/* /*
Zweck: Zweck:
@ -46,8 +43,8 @@ class HandlerRadioQuestion(
Html.fromHtml(LanguageManager.getText(languageID, it), Html.FROM_HTML_MODE_LEGACY) Html.fromHtml(LanguageManager.getText(languageID, it), Html.FROM_HTML_MODE_LEGACY)
} ?: "" } ?: ""
ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f) questionTextView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTitle, 0.03f) questionTitle.setTextSizePercentOfScreenHeight(0.03f)
radioGroup.removeAllViews() radioGroup.removeAllViews()
@ -56,8 +53,7 @@ class HandlerRadioQuestion(
text = LanguageManager.getText(languageID, option.key) text = LanguageManager.getText(languageID, option.key)
tag = option.key tag = option.key
// RadioButton-Text analog zu EditTexts: 2.5% der Bildschirmhöhe setTextSizePercentOfScreenHeight(0.025f)
ViewUtils.setTextSizePercentOfScreenHeight(this, 0.025f)
layoutParams = RadioGroup.LayoutParams( layoutParams = RadioGroup.LayoutParams(
RadioGroup.LayoutParams.MATCH_PARENT, RadioGroup.LayoutParams.MATCH_PARENT,
@ -83,7 +79,7 @@ class HandlerRadioQuestion(
val clientCode = GlobalValues.LAST_CLIENT_CODE val clientCode = GlobalValues.LAST_CLIENT_CODE
if (clientCode.isNullOrBlank()) return@launch if (clientCode.isNullOrBlank()) return@launch
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) val allAnswersForClient = MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
val myQuestionId = questionnaireMeta + "-" + question.question val myQuestionId = questionnaireMeta + "-" + question.question
val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue

View File

@ -1,17 +1,15 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import com.dano.test1.ui.Countries import com.dano.test1.util.LanguageManager
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.LanguageManager import com.dano.test1.util.setupSpinner
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils import com.dano.test1.util.Countries
/* /*
Zweck: Zweck:
@ -46,17 +44,15 @@ class HandlerStringSpinner(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: "" questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: "" textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
// Textgrößen prozentual zur Bildschirmhöhe textView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(textView, 0.03f) questionTextView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
val options = buildOptionsList() val options = buildOptionsList()
// vorhandene Auswahl (falls vorhanden) // vorhandene Auswahl (falls vorhanden)
val savedSelection = question.question?.let { answers[it] as? String } val savedSelection = question.question?.let { answers[it] as? String }
// Spinner aufsetzen spinner.setupSpinner(options, savedSelection)
ViewUtils.setupResponsiveSpinner(context, spinner, options, savedSelection)
// Falls noch keine Antwort im Map: aus DB laden // Falls noch keine Antwort im Map: aus DB laden
val answerMapKey = question.question ?: (question.id ?: "") val answerMapKey = question.question ?: (question.id ?: "")
@ -66,7 +62,7 @@ class HandlerStringSpinner(
val clientCode = GlobalValues.LAST_CLIENT_CODE val clientCode = GlobalValues.LAST_CLIENT_CODE
if (clientCode.isNullOrBlank()) return@launch if (clientCode.isNullOrBlank()) return@launch
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) val allAnswersForClient = MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
val myQuestionId = questionnaireMeta + "-" + question.question val myQuestionId = questionnaireMeta + "-" + question.question
val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue

View File

@ -1,16 +1,14 @@
package com.dano.test1.questionnaire.handlers package com.dano.test1.questionnaire
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.util.LanguageManager
import com.dano.test1.LanguageManager import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.util.setupSpinner
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.utils.ViewUtils
/* /*
Zweck: Zweck:
@ -47,8 +45,8 @@ class HandlerValueSpinner(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: "" questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: "" textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
ViewUtils.setTextSizePercentOfScreenHeight(textView, 0.03f) textView.setTextSizePercentOfScreenHeight(0.03f)
ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f) questionTextView.setTextSizePercentOfScreenHeight(0.03f)
val prompt = LanguageManager.getText(languageID, "choose_answer") val prompt = LanguageManager.getText(languageID, "choose_answer")
val spinnerItems: List<String> = listOf(prompt) + if (question.range != null) { val spinnerItems: List<String> = listOf(prompt) + if (question.range != null) {
@ -58,7 +56,7 @@ class HandlerValueSpinner(
} }
val savedValue = question.question?.let { answers[it] as? String } val savedValue = question.question?.let { answers[it] as? String }
ViewUtils.setupResponsiveSpinner(context, spinner, spinnerItems, savedValue) spinner.setupSpinner(spinnerItems, savedValue)
//DB-Abfrage falls noch keine Antwort im Map existiert //DB-Abfrage falls noch keine Antwort im Map existiert
val answerMapKey = question.question ?: (question.id ?: "") val answerMapKey = question.question ?: (question.id ?: "")
@ -68,7 +66,7 @@ class HandlerValueSpinner(
val clientCode = GlobalValues.LAST_CLIENT_CODE val clientCode = GlobalValues.LAST_CLIENT_CODE
if (clientCode.isNullOrBlank()) return@launch if (clientCode.isNullOrBlank()) return@launch
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) val allAnswersForClient = MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
val myQuestionId = questionnaireMeta + "-" + question.question val myQuestionId = questionnaireMeta + "-" + question.question
val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue

View File

@ -5,19 +5,10 @@ import android.app.Activity
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.data.* import com.dano.test1.data.*
import com.dano.test1.questionnaire.handlers.HandlerClientCoachCode
import com.dano.test1.questionnaire.handlers.HandlerClientNotSigned
import com.dano.test1.questionnaire.handlers.HandlerDateSpinner
import com.dano.test1.questionnaire.handlers.HandlerGlassScaleQuestion
import com.dano.test1.questionnaire.handlers.HandlerLastPage
import com.dano.test1.questionnaire.handlers.HandlerMultiCheckboxQuestion
import com.dano.test1.questionnaire.handlers.HandlerRadioQuestion
import com.dano.test1.questionnaire.handlers.HandlerStringSpinner
import com.dano.test1.questionnaire.handlers.HandlerValueSpinner
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonParser import com.google.gson.JsonParser
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -185,7 +176,7 @@ abstract class QuestionnaireBase<T> {
suspend fun saveAnswersToDatabase(answers: Map<String, Any>, questionnaireId: String) { suspend fun saveAnswersToDatabase(answers: Map<String, Any>, questionnaireId: String) {
Log.d("AnswersMap", answers.toString()) Log.d("AnswersMap", answers.toString())
val db = MyApp.database val db = MyApp.Companion.database
val clientCode = answers["client_code"] as? String ?: return val clientCode = answers["client_code"] as? String ?: return

View File

@ -1,7 +1,7 @@
package com.dano.test1.questionnaire package com.dano.test1.questionnaire
import android.widget.Button import android.widget.Button
import com.dano.test1.LocalizationHelper import com.dano.test1.util.LocalizationHelper
import com.dano.test1.R import com.dano.test1.R
open class QuestionnaireGeneric(private val questionnaireFileName: String) : QuestionnaireBase<Unit>() { open class QuestionnaireGeneric(private val questionnaireFileName: String) : QuestionnaireBase<Unit>() {

View File

@ -4,19 +4,28 @@ import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.* import android.widget.Button
import com.dano.test1.data.ExcelExportService import android.widget.ProgressBar
import com.dano.test1.utils.ViewUtils import android.widget.TableLayout
import com.dano.test1.LanguageManager import android.widget.TableRow
import android.widget.TextView
import android.widget.Toast
import com.dano.test1.export.ExcelExportService
import com.dano.test1.export.HeaderOrderRepository
import com.dano.test1.util.LanguageManager
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.data.Client import com.dano.test1.data.Client
import com.dano.test1.data.HeaderOrderRepository
import com.dano.test1.data.Question import com.dano.test1.data.Question
import com.dano.test1.data.Questionnaire import com.dano.test1.data.Questionnaire
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONArray import org.json.JSONArray
import kotlin.math.roundToInt
class DatabaseButtonHandler( class DatabaseButtonHandler(
private val activity: MainActivity, private val activity: MainActivity,
@ -67,7 +76,7 @@ class DatabaseButtonHandler(
uiScope.launch { uiScope.launch {
val clients: List<Client> = withContext(Dispatchers.IO) { val clients: List<Client> = withContext(Dispatchers.IO) {
MyApp.database.clientDao().getAllClients() MyApp.Companion.database.clientDao().getAllClients()
} }
progress.visibility = View.GONE progress.visibility = View.GONE
@ -154,9 +163,11 @@ class DatabaseButtonHandler(
uiScope.launch { uiScope.launch {
val result = withContext(Dispatchers.IO) { val result = withContext(Dispatchers.IO) {
val allQuestionnairesDb = MyApp.database.questionnaireDao().getAll() val allQuestionnairesDb = MyApp.Companion.database.questionnaireDao().getAll()
val completedForClient = MyApp.database.completedQuestionnaireDao().getAllForClient(clientCode) val completedForClient =
val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode) MyApp.Companion.database.completedQuestionnaireDao().getAllForClient(clientCode)
val allAnswersForClient =
MyApp.Companion.database.answerDao().getAnswersForClient(clientCode)
Triple(allQuestionnairesDb, completedForClient, allAnswersForClient) Triple(allQuestionnairesDb, completedForClient, allAnswersForClient)
} }
@ -275,8 +286,9 @@ class DatabaseButtonHandler(
uiScope.launch { uiScope.launch {
val (questions, answersForClient) = withContext(Dispatchers.IO) { val (questions, answersForClient) = withContext(Dispatchers.IO) {
val qs = MyApp.database.questionDao().getQuestionsForQuestionnaire(questionnaireId) val qs = MyApp.Companion.database.questionDao()
val ans = MyApp.database.answerDao() .getQuestionsForQuestionnaire(questionnaireId)
val ans = MyApp.Companion.database.answerDao()
.getAnswersForClientAndQuestionnaire(clientCode, questionnaireId) .getAnswersForClientAndQuestionnaire(clientCode, questionnaireId)
qs to ans qs to ans
} }
@ -420,7 +432,10 @@ class DatabaseButtonHandler(
bgColor?.let { setBackgroundColor(it) } bgColor?.let { setBackgroundColor(it) }
} }
private fun dp(value: Int): Int = ViewUtils.dp(activity, value) private fun dp(value: Int): Int {
val density = activity.resources.displayMetrics.density
return (value * density).roundToInt()
}
private fun <T : View> requireView(id: Int, name: String): T { private fun <T : View> requireView(id: Int, name: String): T {
val v = activity.findViewById<T>(id) val v = activity.findViewById<T>(id)
@ -467,4 +482,4 @@ class DatabaseButtonHandler(
} catch (_: Exception) { } catch (_: Exception) {
emptyList() emptyList()
} }
} }

View File

@ -3,7 +3,7 @@ package com.dano.test1.ui
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.MyApp import com.dano.test1.MyApp
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -62,7 +62,7 @@ class EditButtonHandler(
} }
val completedEntries: List<CompletedQuestionnaire> = val completedEntries: List<CompletedQuestionnaire> =
MyApp.database.completedQuestionnaireDao().getAllForClient(desiredCode) MyApp.Companion.database.completedQuestionnaireDao().getAllForClient(desiredCode)
val completedFiles = completedEntries.filter { it.isDone }.map { it.questionnaireId.lowercase() } val completedFiles = completedEntries.filter { it.isDone }.map { it.questionnaireId.lowercase() }

View File

@ -10,13 +10,13 @@ import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.R import com.dano.test1.R
import com.dano.test1.auth.LoginManager
import com.dano.test1.auth.TokenStore
import com.dano.test1.network.DatabaseUploader import com.dano.test1.network.DatabaseUploader
import com.dano.test1.network.LoginManager
import com.dano.test1.network.NetworkUtils import com.dano.test1.network.NetworkUtils
import com.dano.test1.network.TokenStore
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.questionnaire.GlobalValues
import com.dano.test1.questionnaire.QuestionItem import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.questionnaire.QuestionnaireBase import com.dano.test1.questionnaire.QuestionnaireBase
@ -27,7 +27,6 @@ import org.json.JSONObject
import java.io.File import java.io.File
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.dano.test1.utils.ViewUtils
var RHS_POINTS: Int? = null var RHS_POINTS: Int? = null
@ -573,7 +572,7 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
} }
} }
private fun dp(v: Int): Int = ViewUtils.dp(activity, v) private fun dp(v: Int): Int = (v * activity.resources.displayMetrics.density).toInt()
private fun isCompleted(button: Button): Boolean { private fun isCompleted(button: Button): Boolean {
val fileName = questionnaireFiles[button] ?: return false val fileName = questionnaireFiles[button] ?: return false
@ -665,7 +664,16 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
} }
private fun lockCoachCodeField() { private fun lockCoachCodeField() {
ViewUtils.lockEditField(coachEditText) coachEditText.isFocusable = false
coachEditText.isFocusableInTouchMode = false
coachEditText.isCursorVisible = false
coachEditText.keyListener = null
coachEditText.isLongClickable = false
coachEditText.isClickable = false
coachEditText.setBackgroundResource(R.drawable.bg_field_locked)
coachEditText.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_24, 0)
coachEditText.compoundDrawablePadding = dp(8)
coachEditText.alpha = 0.95f
} }
private fun applySessionAgeHighlight(ageMs: Long) { private fun applySessionAgeHighlight(ageMs: Long) {

View File

@ -3,7 +3,7 @@ package com.dano.test1.ui
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.MyApp import com.dano.test1.MyApp
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -45,7 +45,7 @@ class LoadButtonHandler(
GlobalValues.LAST_CLIENT_CODE = clientCode GlobalValues.LAST_CLIENT_CODE = clientCode
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
val client = MyApp.database.clientDao().getClientByCode(clientCode) val client = MyApp.Companion.database.clientDao().getClientByCode(clientCode)
if (client == null) { if (client == null) {
GlobalValues.LOADED_CLIENT_CODE = null GlobalValues.LOADED_CLIENT_CODE = null
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@ -85,7 +85,7 @@ class LoadButtonHandler(
} }
} }
is QuestionItem.Condition.QuestionCondition -> { is QuestionItem.Condition.QuestionCondition -> {
val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, condition.questionnaire) val answers = MyApp.Companion.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, condition.questionnaire)
val relevant = answers.find { it.questionId.endsWith(condition.questionId, ignoreCase = true) } val relevant = answers.find { it.questionId.endsWith(condition.questionId, ignoreCase = true) }
val answerValue = relevant?.answerValue ?: "" val answerValue = relevant?.answerValue ?: ""
when (condition.operator) { when (condition.operator) {
@ -102,7 +102,7 @@ class LoadButtonHandler(
} }
if (!reqOk) return false if (!reqOk) return false
val q = condition.questionCheck ?: return true val q = condition.questionCheck ?: return true
val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, q.questionnaire) val answers = MyApp.Companion.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, q.questionnaire)
val relevant = answers.find { it.questionId.endsWith(q.questionId, ignoreCase = true) } val relevant = answers.find { it.questionId.endsWith(q.questionId, ignoreCase = true) }
val answerValue = relevant?.answerValue ?: "" val answerValue = relevant?.answerValue ?: ""
when (q.operator) { when (q.operator) {
@ -122,7 +122,7 @@ class LoadButtonHandler(
private suspend fun handleNormalLoad(clientCode: String) { private suspend fun handleNormalLoad(clientCode: String) {
val completedEntries = withContext(Dispatchers.IO) { val completedEntries = withContext(Dispatchers.IO) {
MyApp.database.completedQuestionnaireDao().getAllForClient(clientCode) MyApp.Companion.database.completedQuestionnaireDao().getAllForClient(clientCode)
} }
buttonPoints.clear() buttonPoints.clear()

View File

@ -12,7 +12,7 @@ import android.util.Log
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
import com.dano.test1.MainActivity import com.dano.test1.MainActivity
import com.dano.test1.MyApp import com.dano.test1.MyApp
import com.dano.test1.questionnaire.GlobalValues import com.dano.test1.questionnaire.GlobalValues
@ -44,7 +44,7 @@ class SaveButtonHandler(
private fun showCompletedQuestionnaires(clientCode: String) { private fun showCompletedQuestionnaires(clientCode: String) {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
val actualClientCode = clientCode.removeSuffix("_database") val actualClientCode = clientCode.removeSuffix("_database")
val completedEntries = MyApp.database.completedQuestionnaireDao().getAllForClient(actualClientCode) val completedEntries = MyApp.Companion.database.completedQuestionnaireDao().getAllForClient(actualClientCode)
Log.d("PDF_DEBUG", "Completed entries for client $actualClientCode:") Log.d("PDF_DEBUG", "Completed entries for client $actualClientCode:")
for (entry in completedEntries) { for (entry in completedEntries) {
@ -74,7 +74,7 @@ class SaveButtonHandler(
canvas.drawText("Points: ${entry.sumPoints ?: "N/A"}", 20f, yPosition, paint) canvas.drawText("Points: ${entry.sumPoints ?: "N/A"}", 20f, yPosition, paint)
yPosition += 30f yPosition += 30f
val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(actualClientCode, entry.questionnaireId) val answers = MyApp.Companion.database.answerDao().getAnswersForClientAndQuestionnaire(actualClientCode, entry.questionnaireId)
for (answer in answers) { for (answer in answers) {
val questionKey = answer.questionId.substringAfter("-") val questionKey = answer.questionId.substringAfter("-")

View File

@ -1,6 +1,6 @@
package com.dano.test1.ui package com.dano.test1.util
import com.dano.test1.LanguageManager import com.dano.test1.util.LanguageManager
object Countries { object Countries {
fun getAllCountries(languageID: String): List<String> { fun getAllCountries(languageID: String): List<String> {

View File

@ -1,4 +1,4 @@
package com.dano.test1 package com.dano.test1.util
import com.dano.test1.questionnaire.MAX_VALUE_AGE import com.dano.test1.questionnaire.MAX_VALUE_AGE
import com.dano.test1.questionnaire.MAX_VALUE_YEAR import com.dano.test1.questionnaire.MAX_VALUE_YEAR

View File

@ -1,4 +1,4 @@
package com.dano.test1 package com.dano.test1.util
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup

View File

@ -1,13 +1,11 @@
package com.dano.test1.ui package com.dano.test1.util
import com.dano.test1.LanguageManager
data class Month(val name: String) { data class Month(val name: String) {
override fun toString(): String = name override fun toString(): String = name
} }
object Months { object Months {
fun getAllMonths(languageID: String): List<Any> { fun getAllMonths(languageID: String): List<Month> {
return listOf( return listOf(
Month(LanguageManager.getText(languageID, "january")), Month(LanguageManager.getText(languageID, "january")),
Month(LanguageManager.getText(languageID, "february")), Month(LanguageManager.getText(languageID, "february")),

View File

@ -0,0 +1,73 @@
package com.dano.test1.util
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.AbsListView
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.TextView
import androidx.core.widget.TextViewCompat
fun TextView.setTextSizePercentOfScreenHeight(percentOfHeight: Float) {
val dm = context.resources.displayMetrics
val sp = (dm.heightPixels * percentOfHeight) / dm.scaledDensity
TextViewCompat.setAutoSizeTextTypeWithDefaults(this, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
setTextSize(TypedValue.COMPLEX_UNIT_SP, sp)
}
fun <T> Spinner.setupSpinner(items: List<T>, selectedItem: T?) {
val dm = context.resources.displayMetrics
fun spFromScreenHeight(percent: Float): Float = (dm.heightPixels * percent) / dm.scaledDensity
fun pxFromSp(sp: Float): Int = (sp * dm.scaledDensity).toInt()
val textSp = spFromScreenHeight(0.0275f)
val textPx = pxFromSp(textSp)
val vPadPx = (textPx * 0.50f).toInt()
val rowHeight = (textPx * 2.20f + 2 * vPadPx).toInt()
val adapter = object : ArrayAdapter<T>(context, android.R.layout.simple_spinner_item, items) {
private fun styleRow(tv: TextView, forceHeight: Boolean) {
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSp)
tv.includeFontPadding = true
tv.setLineSpacing(0f, 1.2f)
tv.gravity = (tv.gravity and Gravity.HORIZONTAL_GRAVITY_MASK) or Gravity.CENTER_VERTICAL
tv.setPadding(tv.paddingLeft, vPadPx, tv.paddingRight, vPadPx)
tv.minHeight = rowHeight
tv.isSingleLine = true
if (forceHeight) {
val lp = tv.layoutParams
if (lp == null || lp.height <= 0) {
tv.layoutParams = AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, rowHeight)
} else {
lp.height = rowHeight
}
}
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val v = super.getView(position, convertView, parent) as TextView
styleRow(v, forceHeight = false)
return v
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
val v = super.getDropDownView(position, convertView, parent) as TextView
styleRow(v, forceHeight = true)
return v
}
}
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
this.adapter = adapter
setPadding(paddingLeft, vPadPx, paddingRight, vPadPx)
minimumHeight = rowHeight
requestLayout()
selectedItem?.let {
val index = items.indexOf(it)
if (index >= 0) setSelection(index)
}
}

View File

@ -1,110 +0,0 @@
package com.dano.test1.utils
import android.content.Context
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.AbsListView
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.Spinner
import android.widget.TextView
import androidx.core.widget.TextViewCompat
import com.dano.test1.R
import kotlin.math.roundToInt
object ViewUtils {
/**
* Sets the text size of a TextView to a percentage of the screen height (in sp).
* Disables auto-sizing to prevent conflicts.
*/
fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
val dm = view.context.resources.displayMetrics
val sp = (dm.heightPixels * percentOfHeight) / dm.scaledDensity
TextViewCompat.setAutoSizeTextTypeWithDefaults(view, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
view.setTextSize(TypedValue.COMPLEX_UNIT_SP, sp)
}
/**
* Sets up a Spinner with a responsive, styled adapter.
* Font size and row height are derived from screen height to prevent clipping.
*/
fun <T> setupResponsiveSpinner(context: Context, spinner: Spinner, items: List<T>, selectedItem: T?) {
val dm = context.resources.displayMetrics
fun spFromScreenHeight(percent: Float): Float = (dm.heightPixels * percent) / dm.scaledDensity
fun pxFromSp(sp: Float): Int = (sp * dm.scaledDensity).toInt()
val textSp = spFromScreenHeight(0.0275f)
val textPx = pxFromSp(textSp)
val vPadPx = (textPx * 0.50f).toInt()
val rowHeight = (textPx * 2.20f + 2 * vPadPx).toInt()
val adapter = object : ArrayAdapter<T>(context, android.R.layout.simple_spinner_item, items) {
private fun styleRow(tv: TextView, forceHeight: Boolean) {
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSp)
tv.includeFontPadding = true
tv.setLineSpacing(0f, 1.2f)
tv.gravity = (tv.gravity and Gravity.HORIZONTAL_GRAVITY_MASK) or Gravity.CENTER_VERTICAL
tv.setPadding(tv.paddingLeft, vPadPx, tv.paddingRight, vPadPx)
tv.minHeight = rowHeight
tv.isSingleLine = true
if (forceHeight) {
val lp = tv.layoutParams
if (lp == null || lp.height <= 0) {
tv.layoutParams = AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, rowHeight)
} else {
lp.height = rowHeight
}
}
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val v = super.getView(position, convertView, parent) as TextView
styleRow(v, forceHeight = false)
return v
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
val v = super.getDropDownView(position, convertView, parent) as TextView
styleRow(v, forceHeight = true)
return v
}
}
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
spinner.setPadding(spinner.paddingLeft, vPadPx, spinner.paddingRight, vPadPx)
spinner.minimumHeight = rowHeight
spinner.requestLayout()
selectedItem?.let {
val index = items.indexOf(it)
if (index >= 0) spinner.setSelection(index)
}
}
/**
* Locks an EditText field visually and functionally (e.g. for coach code fields).
*/
fun lockEditField(field: EditText, dpPadding: Int = 8) {
field.isFocusable = false
field.isFocusableInTouchMode = false
field.isCursorVisible = false
field.keyListener = null
field.isLongClickable = false
field.isClickable = false
field.setBackgroundResource(R.drawable.bg_field_locked)
field.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_24, 0)
field.compoundDrawablePadding = dp(field.context, dpPadding)
field.alpha = 0.95f
}
/**
* Converts dp to pixels using the given context.
*/
fun dp(context: Context, value: Int): Int =
(value * context.resources.displayMetrics.density).roundToInt()
}