Compare commits
2 Commits
refactorin
...
092242f913
| Author | SHA1 | Date | |
|---|---|---|---|
| 092242f913 | |||
| e69be2ec6f |
@ -13,7 +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 java.io.File
|
import com.dano.test1.auth.LoginManager
|
||||||
|
import com.dano.test1.auth.TokenStore
|
||||||
|
import com.dano.test1.network.DatabaseDownloader
|
||||||
|
import com.dano.test1.questionnaire.QuestionnaireBase
|
||||||
|
import com.dano.test1.ui.HandlerOpeningScreen
|
||||||
|
import com.dano.test1.util.LanguageManager
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.auth
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.text.InputType
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -96,13 +96,13 @@ object LoginManager {
|
|||||||
}
|
}
|
||||||
val etNew = EditText(context).apply {
|
val etNew = EditText(context).apply {
|
||||||
hint = "Neues Passwort"
|
hint = "Neues Passwort"
|
||||||
inputType = android.text.InputType.TYPE_CLASS_TEXT or
|
inputType = InputType.TYPE_CLASS_TEXT or
|
||||||
android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
|
InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
}
|
}
|
||||||
val etRepeat = EditText(context).apply {
|
val etRepeat = EditText(context).apply {
|
||||||
hint = "Neues Passwort (wiederholen)"
|
hint = "Neues Passwort (wiederholen)"
|
||||||
inputType = android.text.InputType.TYPE_CLASS_TEXT or
|
inputType = InputType.TYPE_CLASS_TEXT or
|
||||||
android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
|
InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
}
|
}
|
||||||
container.addView(etNew)
|
container.addView(etNew)
|
||||||
container.addView(etRepeat)
|
container.addView(etRepeat)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.auth
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.export
|
||||||
|
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -7,8 +7,12 @@ 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.util.LanguageManager
|
||||||
|
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
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Aufgabe:
|
Aufgabe:
|
||||||
@ -37,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()
|
||||||
@ -67,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 ->
|
||||||
@ -83,7 +87,7 @@ class ExcelExportService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val bytes = java.io.ByteArrayOutputStream().use { bos ->
|
val bytes = ByteArrayOutputStream().use { bos ->
|
||||||
wb.write(bos); bos.toByteArray()
|
wb.write(bos); bos.toByteArray()
|
||||||
}
|
}
|
||||||
wb.close()
|
wb.close()
|
||||||
@ -112,7 +116,7 @@ class ExcelExportService(
|
|||||||
} else {
|
} else {
|
||||||
val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||||
if (!downloadsDir.exists()) downloadsDir.mkdirs()
|
if (!downloadsDir.exists()) downloadsDir.mkdirs()
|
||||||
val outFile = java.io.File(downloadsDir, filename)
|
val outFile = File(downloadsDir, filename)
|
||||||
outFile.writeBytes(bytes)
|
outFile.writeBytes(bytes)
|
||||||
MediaScannerConnection.scanFile(
|
MediaScannerConnection.scanFile(
|
||||||
context,
|
context,
|
||||||
@ -1,8 +1,11 @@
|
|||||||
package com.dano.test1
|
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.util.LanguageManager
|
||||||
|
import org.apache.poi.ss.usermodel.CellType
|
||||||
|
import org.apache.poi.ss.usermodel.DateUtil
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -63,16 +66,16 @@ class HeaderOrderRepository(
|
|||||||
for (i in first until last) {
|
for (i in first until last) {
|
||||||
val cell = row.getCell(i) ?: continue
|
val cell = row.getCell(i) ?: continue
|
||||||
val value = when (cell.cellType) {
|
val value = when (cell.cellType) {
|
||||||
org.apache.poi.ss.usermodel.CellType.STRING -> cell.stringCellValue
|
CellType.STRING -> cell.stringCellValue
|
||||||
org.apache.poi.ss.usermodel.CellType.NUMERIC ->
|
CellType.NUMERIC ->
|
||||||
if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell))
|
if (DateUtil.isCellDateFormatted(cell))
|
||||||
cell.dateCellValue.time.toString()
|
cell.dateCellValue.time.toString()
|
||||||
else {
|
else {
|
||||||
val n = cell.numericCellValue
|
val n = cell.numericCellValue
|
||||||
if (n % 1.0 == 0.0) n.toLong().toString() else n.toString()
|
if (n % 1.0 == 0.0) n.toLong().toString() else n.toString()
|
||||||
}
|
}
|
||||||
org.apache.poi.ss.usermodel.CellType.BOOLEAN -> cell.booleanCellValue.toString()
|
CellType.BOOLEAN -> cell.booleanCellValue.toString()
|
||||||
org.apache.poi.ss.usermodel.CellType.FORMULA -> cell.richStringCellValue.string
|
CellType.FORMULA -> cell.richStringCellValue.string
|
||||||
else -> ""
|
else -> ""
|
||||||
}.trim()
|
}.trim()
|
||||||
|
|
||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
@ -1,9 +1,12 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import android.util.TypedValue
|
import com.dano.test1.util.LanguageManager
|
||||||
import androidx.core.widget.TextViewCompat
|
import com.dano.test1.util.setTextSizePercentOfScreenHeight
|
||||||
|
import com.dano.test1.MyApp
|
||||||
|
import com.dano.test1.R
|
||||||
|
import com.dano.test1.auth.TokenStore
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -38,10 +41,10 @@ class HandlerClientCoachCode(
|
|||||||
|
|
||||||
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
|
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
|
||||||
|
|
||||||
setTextSizePercentOfScreenHeight(titleTextView, 0.03f)
|
titleTextView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
|
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(clientCodeField, 0.025f)
|
clientCodeField.setTextSizePercentOfScreenHeight(0.025f)
|
||||||
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
|
||||||
@ -72,13 +75,6 @@ class HandlerClientCoachCode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = layout.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onNextClicked(clientCodeField: EditText, coachCodeField: EditText) {
|
private fun onNextClicked(clientCodeField: EditText, coachCodeField: EditText) {
|
||||||
val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE
|
val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE
|
||||||
|
|
||||||
@ -97,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) {
|
||||||
@ -108,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()
|
||||||
@ -1,7 +1,9 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
import com.dano.test1.util.LanguageManager
|
||||||
|
import com.dano.test1.R
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -1,15 +1,18 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import android.util.TypedValue
|
import com.dano.test1.util.LanguageManager
|
||||||
import androidx.core.widget.TextViewCompat
|
import com.dano.test1.util.setTextSizePercentOfScreenHeight
|
||||||
import android.widget.AbsListView
|
import com.dano.test1.util.setupSpinner
|
||||||
|
import com.dano.test1.util.Month
|
||||||
|
import com.dano.test1.util.Months
|
||||||
|
import com.dano.test1.MyApp
|
||||||
|
import com.dano.test1.R
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -51,13 +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)
|
||||||
setTextSizePercentOfScreenHeight(textView, 0.03f) // oben
|
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(questionTextView, 0.03f) // frage
|
labelDay.setTextSizePercentOfScreenHeight(0.025f)
|
||||||
setTextSizePercentOfScreenHeight(labelDay, 0.025f)
|
labelMonth.setTextSizePercentOfScreenHeight(0.025f)
|
||||||
setTextSizePercentOfScreenHeight(labelMonth, 0.025f)
|
labelYear.setTextSizePercentOfScreenHeight(0.025f)
|
||||||
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 {
|
||||||
@ -74,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)
|
||||||
setupSpinner(spinnerDay, days, defaultDay)
|
spinnerMonth.setupSpinner(months, defaultMonth)
|
||||||
setupSpinner(spinnerMonth, months, defaultMonth)
|
spinnerYear.setupSpinner(years, defaultYear)
|
||||||
setupSpinner(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 ?: "")
|
||||||
@ -87,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
|
||||||
|
|
||||||
@ -207,71 +207,4 @@ class HandlerDateSpinner(
|
|||||||
return sdf.parse(dateString)
|
return sdf.parse(dateString)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Textgröße prozentual zur Bildschirmhöhe (in sp)
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spinner-Adapter: Schrift & Zeilenhöhe dynamisch, kein Abschneiden
|
|
||||||
private fun <T> setupSpinner(spinner: Spinner, items: List<T>, defaultSelection: 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) // ~2.75% der Bildschirmhöhe
|
|
||||||
val textPx = pxFromSp(textSp)
|
|
||||||
val vPadPx = (textPx * 0.50f).toInt() // vertikales Padding
|
|
||||||
val rowHeight = (textPx * 2.20f + 2 * vPadPx).toInt() // feste Zeilenhöhe
|
|
||||||
|
|
||||||
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 android.view.Gravity.HORIZONTAL_GRAVITY_MASK) or android.view.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()
|
|
||||||
|
|
||||||
defaultSelection?.let {
|
|
||||||
val index = items.indexOf(it)
|
|
||||||
if (index >= 0) spinner.setSelection(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,11 +1,14 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.TypedValue
|
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 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.R
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -67,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) } ?: ""
|
||||||
|
|
||||||
setTextSizePercentOfScreenHeight(titleTv, 0.03f)
|
titleTv.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
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)
|
||||||
@ -102,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) {
|
||||||
@ -150,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)
|
||||||
setTextSizePercentOfScreenHeight(this, 0.022f)
|
setTextSizePercentOfScreenHeight(0.022f)
|
||||||
}
|
}
|
||||||
row.addView(symptomText)
|
row.addView(symptomText)
|
||||||
|
|
||||||
@ -277,10 +280,4 @@ class HandlerGlassScaleQuestion(
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,12 +1,15 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.core.widget.TextViewCompat
|
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.R
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -57,9 +60,8 @@ class HandlerLastPage(
|
|||||||
finishBtn.isAllCaps = false
|
finishBtn.isAllCaps = false
|
||||||
applyResponsiveTextSizing(finishBtn)
|
applyResponsiveTextSizing(finishBtn)
|
||||||
|
|
||||||
// Überschriften responsiv skalieren (wie zuvor)
|
titleTv.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(titleTv, 0.03f)
|
questionTv.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(questionTv, 0.03f)
|
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
prevBtn.setOnClickListener { goToPreviousQuestion() }
|
prevBtn.setOnClickListener { goToPreviousQuestion() }
|
||||||
@ -128,14 +130,6 @@ class HandlerLastPage(
|
|||||||
}
|
}
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
// Helper: Textgröße prozentual zur Bildschirmhöhe setzen (in sp)
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun sumPoints(): Int =
|
private fun sumPoints(): Int =
|
||||||
answers.filterKeys { it.endsWith("_points") }
|
answers.filterKeys { it.endsWith("_points") }
|
||||||
.values.mapNotNull { it as? Int }
|
.values.mapNotNull { it as? Int }
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -6,6 +6,10 @@ import android.widget.*
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import androidx.core.widget.TextViewCompat
|
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.R
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -37,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)
|
||||||
setTextSizePercentOfScreenHeight(questionTextView, 0.03f) // Überschrift
|
questionTitle.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(questionTitle, 0.03f) // Frage
|
|
||||||
|
|
||||||
container.removeAllViews()
|
container.removeAllViews()
|
||||||
|
|
||||||
@ -88,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
|
||||||
|
|
||||||
@ -204,10 +207,4 @@ class HandlerMultiCheckboxQuestion(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,12 +1,14 @@
|
|||||||
package com.dano.test1
|
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 android.util.TypedValue
|
import com.dano.test1.util.LanguageManager
|
||||||
import androidx.core.widget.TextViewCompat // <— hinzugefügt
|
import com.dano.test1.util.setTextSizePercentOfScreenHeight
|
||||||
|
import com.dano.test1.MyApp
|
||||||
|
import com.dano.test1.R
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -41,11 +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)
|
||||||
} ?: ""
|
} ?: ""
|
||||||
|
|
||||||
//
|
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
// Titel/Frage: 3% der Bildschirmhöhe
|
questionTitle.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
|
|
||||||
setTextSizePercentOfScreenHeight(questionTitle, 0.03f)
|
|
||||||
// ===================================================
|
|
||||||
|
|
||||||
radioGroup.removeAllViews()
|
radioGroup.removeAllViews()
|
||||||
|
|
||||||
@ -54,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)
|
||||||
setTextSizePercentOfScreenHeight(this, 0.025f)
|
|
||||||
|
|
||||||
layoutParams = RadioGroup.LayoutParams(
|
layoutParams = RadioGroup.LayoutParams(
|
||||||
RadioGroup.LayoutParams.MATCH_PARENT,
|
RadioGroup.LayoutParams.MATCH_PARENT,
|
||||||
@ -81,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
|
||||||
|
|
||||||
@ -137,15 +135,6 @@ class HandlerRadioQuestion(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setzt Textgröße prozentual zur Bildschirmhöhe (in sp)
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
// ————————————————————————————————————————————————————————————————
|
|
||||||
|
|
||||||
private fun restorePreviousAnswer(radioGroup: RadioGroup) {
|
private fun restorePreviousAnswer(radioGroup: RadioGroup) {
|
||||||
question.question?.let { questionKey ->
|
question.question?.let { questionKey ->
|
||||||
val savedAnswer = answers[questionKey] as? String
|
val savedAnswer = answers[questionKey] as? String
|
||||||
@ -1,13 +1,15 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import android.util.TypedValue
|
import com.dano.test1.util.LanguageManager
|
||||||
import android.widget.TextView
|
import com.dano.test1.util.setTextSizePercentOfScreenHeight
|
||||||
import androidx.core.widget.TextViewCompat
|
import com.dano.test1.util.setupSpinner
|
||||||
|
import com.dano.test1.MyApp
|
||||||
|
import com.dano.test1.R
|
||||||
|
import com.dano.test1.util.Countries
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -42,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 (wie im HandlerRadioQuestion)
|
textView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(textView, 0.03f)
|
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
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)
|
||||||
setupSpinner(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 ?: "")
|
||||||
@ -62,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
|
||||||
|
|
||||||
@ -119,73 +119,4 @@ class HandlerStringSpinner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Textgröße prozentual zur Bildschirmhöhe setzen und AutoSize deaktivieren
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spinner-Adapter mit dynamischer Schrift & stabiler Dropdown-Zeilenhöhe (kein Abschneiden)
|
|
||||||
private fun <T> setupSpinner(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()
|
|
||||||
|
|
||||||
// Schrift & abgeleitete Höhen (wie beim Value-Spinner-Fix)
|
|
||||||
val textSp = spFromScreenHeight(0.0275f) // ~2.75% der Bildschirmhöhe
|
|
||||||
val textPx = pxFromSp(textSp)
|
|
||||||
val vPadPx = (textPx * 0.50f).toInt() // vertikales Padding
|
|
||||||
val rowHeight = (textPx * 2.20f + 2 * vPadPx).toInt() // feste Zeilenhöhe, verhindert Abschneiden
|
|
||||||
|
|
||||||
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 android.view.Gravity.HORIZONTAL_GRAVITY_MASK) or android.view.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) // ausgewählte Ansicht
|
|
||||||
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) // Dropdown-Zeilen: Höhe erzwingen
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
|
||||||
spinner.adapter = adapter
|
|
||||||
|
|
||||||
// Spinner selbst ausreichend hoch machen
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,12 +1,14 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import android.util.TypedValue
|
import com.dano.test1.util.LanguageManager
|
||||||
import androidx.core.widget.TextViewCompat // <- NEU
|
import com.dano.test1.util.setTextSizePercentOfScreenHeight
|
||||||
|
import com.dano.test1.util.setupSpinner
|
||||||
|
import com.dano.test1.MyApp
|
||||||
|
import com.dano.test1.R
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Zweck:
|
Zweck:
|
||||||
@ -43,10 +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) } ?: ""
|
||||||
|
|
||||||
// Schriftgrößen wie im HandlerRadioQuestion
|
textView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
// Titel/Frage: 3% der Bildschirmhöhe
|
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
|
||||||
setTextSizePercentOfScreenHeight(textView, 0.03f)
|
|
||||||
setTextSizePercentOfScreenHeight(questionTextView, 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) {
|
||||||
@ -56,7 +56,7 @@ class HandlerValueSpinner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val savedValue = question.question?.let { answers[it] as? String }
|
val savedValue = question.question?.let { answers[it] as? String }
|
||||||
setupSpinner(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 ?: "")
|
||||||
@ -66,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
|
||||||
|
|
||||||
@ -127,72 +127,4 @@ class HandlerValueSpinner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setzt Textgröße prozentual zur Bildschirmhöhe (in sp)
|
|
||||||
private fun setTextSizePercentOfScreenHeight(view: TextView, percentOfHeight: Float) {
|
|
||||||
val dm = (view.context ?: layout.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T> setupSpinner(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()
|
|
||||||
|
|
||||||
// Schrift & abgeleitete Höhen
|
|
||||||
val textSp = spFromScreenHeight(0.0275f) // ~2.75% der Bildschirmhöhe
|
|
||||||
val textPx = pxFromSp(textSp)
|
|
||||||
val vPadPx = (textPx * 0.50f).toInt() // vertikales Padding
|
|
||||||
val rowHeight = (textPx * 2.20f + 2 * vPadPx).toInt() // feste Zeilenhöhe
|
|
||||||
|
|
||||||
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 android.view.Gravity.HORIZONTAL_GRAVITY_MASK) or android.view.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) // ausgewählte Ansicht
|
|
||||||
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) // Dropdown-Zeilen: Höhe erzwingen
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
|
||||||
spinner.adapter = adapter
|
|
||||||
|
|
||||||
// Spinner selbst ausreichend hoch machen
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
|
||||||
interface QuestionHandler {
|
interface QuestionHandler {
|
||||||
@ -1,9 +1,13 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
|
import android.R
|
||||||
import android.app.Activity
|
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.util.LanguageManager
|
||||||
|
import com.dano.test1.MainActivity
|
||||||
|
import com.dano.test1.MyApp
|
||||||
import com.dano.test1.data.*
|
import com.dano.test1.data.*
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
@ -61,8 +65,8 @@ abstract class QuestionnaireBase<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun setupSpinner(spinner: Spinner, spinnerValues: List<Any>, selectedValue: Any?) {
|
protected fun setupSpinner(spinner: Spinner, spinnerValues: List<Any>, selectedValue: Any?) {
|
||||||
val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, spinnerValues).apply {
|
val adapter = ArrayAdapter(context, R.layout.simple_spinner_item, spinnerValues).apply {
|
||||||
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
setDropDownViewResource(R.layout.simple_spinner_dropdown_item)
|
||||||
}
|
}
|
||||||
spinner.adapter = adapter
|
spinner.adapter = adapter
|
||||||
selectedValue?.let { value ->
|
selectedValue?.let { value ->
|
||||||
@ -75,7 +79,7 @@ abstract class QuestionnaireBase<T> {
|
|||||||
|
|
||||||
protected fun navigateTo(layoutResId: Int, setup: (View) -> Unit) {
|
protected fun navigateTo(layoutResId: Int, setup: (View) -> Unit) {
|
||||||
context.setContentView(layoutResId)
|
context.setContentView(layoutResId)
|
||||||
val rootView = context.findViewById<View>(android.R.id.content)
|
val rootView = context.findViewById<View>(R.id.content)
|
||||||
setup(rootView)
|
setup(rootView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +89,7 @@ abstract class QuestionnaireBase<T> {
|
|||||||
|
|
||||||
protected fun showEmptyScreen() {
|
protected fun showEmptyScreen() {
|
||||||
navigateTo(getLayoutResId("empty")) {
|
navigateTo(getLayoutResId("empty")) {
|
||||||
setupPrevButton(R.id.Qprev) { goToPreviousQuestion() }
|
setupPrevButton(com.dano.test1.R.id.Qprev) { goToPreviousQuestion() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,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
|
||||||
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import com.dano.test1.util.LocalizationHelper
|
||||||
|
import com.dano.test1.R
|
||||||
|
|
||||||
open class QuestionnaireGeneric(private val questionnaireFileName: String) : QuestionnaireBase<Unit>() {
|
open class QuestionnaireGeneric(private val questionnaireFileName: String) : QuestionnaireBase<Unit>() {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.questionnaire
|
||||||
|
|
||||||
data class Option(
|
data class Option(
|
||||||
val key: String, // Must always be set
|
val key: String, // Must always be set
|
||||||
@ -1,14 +1,31 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.ui
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
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 android.widget.ProgressBar
|
||||||
|
import android.widget.TableLayout
|
||||||
|
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.MyApp
|
||||||
|
import com.dano.test1.R
|
||||||
import com.dano.test1.data.Client
|
import com.dano.test1.data.Client
|
||||||
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 kotlin.math.roundToInt
|
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,
|
||||||
@ -59,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
|
||||||
@ -146,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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,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
|
||||||
}
|
}
|
||||||
@ -361,7 +381,7 @@ class DatabaseButtonHandler(
|
|||||||
val row = TableRow(activity).apply {
|
val row = TableRow(activity).apply {
|
||||||
isClickable = true
|
isClickable = true
|
||||||
isFocusable = true
|
isFocusable = true
|
||||||
setBackgroundColor(android.graphics.Color.TRANSPARENT)
|
setBackgroundColor(Color.TRANSPARENT)
|
||||||
setOnClickListener { onClick() }
|
setOnClickListener { onClick() }
|
||||||
}
|
}
|
||||||
cells.forEachIndexed { index, text ->
|
cells.forEachIndexed { index, text ->
|
||||||
@ -396,7 +416,7 @@ class DatabaseButtonHandler(
|
|||||||
this.text = text
|
this.text = text
|
||||||
setPadding(dp(12), dp(10), dp(12), dp(10))
|
setPadding(dp(12), dp(10), dp(12), dp(10))
|
||||||
textSize = 16f
|
textSize = 16f
|
||||||
setTypeface(typeface, android.graphics.Typeface.BOLD)
|
setTypeface(typeface, Typeface.BOLD)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeBodyCell(
|
private fun makeBodyCell(
|
||||||
@ -462,4 +482,4 @@ class DatabaseButtonHandler(
|
|||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,10 +1,14 @@
|
|||||||
package com.dano.test1
|
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.util.LanguageManager
|
||||||
|
import com.dano.test1.MainActivity
|
||||||
|
import com.dano.test1.MyApp
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.data.CompletedQuestionnaire
|
import com.dano.test1.data.CompletedQuestionnaire
|
||||||
|
import com.dano.test1.questionnaire.GlobalValues
|
||||||
|
|
||||||
class EditButtonHandler(
|
class EditButtonHandler(
|
||||||
private val activity: MainActivity,
|
private val activity: MainActivity,
|
||||||
@ -58,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() }
|
||||||
|
|
||||||
@ -1,13 +1,26 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.TypedValue
|
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.util.LanguageManager
|
||||||
|
import com.dano.test1.MainActivity
|
||||||
|
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.NetworkUtils
|
||||||
|
import com.dano.test1.questionnaire.GlobalValues
|
||||||
|
import com.dano.test1.questionnaire.QuestionItem
|
||||||
|
import com.dano.test1.questionnaire.QuestionnaireBase
|
||||||
|
import com.dano.test1.questionnaire.QuestionnaireGeneric
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
@ -682,22 +695,22 @@ class HandlerOpeningScreen(private val activity: MainActivity) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun showRedToast(ctx: android.content.Context, message: String) {
|
private fun showRedToast(ctx: Context, message: String) {
|
||||||
val tv = android.widget.TextView(ctx).apply {
|
val tv = TextView(ctx).apply {
|
||||||
text = message
|
text = message
|
||||||
setTextColor(android.graphics.Color.WHITE)
|
setTextColor(Color.WHITE)
|
||||||
textSize = 16f
|
textSize = 16f
|
||||||
setPadding(32, 20, 32, 20)
|
setPadding(32, 20, 32, 20)
|
||||||
background = android.graphics.drawable.GradientDrawable().apply {
|
background = GradientDrawable().apply {
|
||||||
shape = android.graphics.drawable.GradientDrawable.RECTANGLE
|
shape = GradientDrawable.RECTANGLE
|
||||||
cornerRadius = 24f
|
cornerRadius = 24f
|
||||||
setColor(android.graphics.Color.parseColor("#D32F2F")) // kräftiges Rot
|
setColor(Color.parseColor("#D32F2F")) // kräftiges Rot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
android.widget.Toast(ctx).apply {
|
Toast(ctx).apply {
|
||||||
duration = android.widget.Toast.LENGTH_LONG
|
duration = Toast.LENGTH_LONG
|
||||||
view = tv
|
view = tv
|
||||||
setGravity(android.view.Gravity.TOP or android.view.Gravity.CENTER_HORIZONTAL, 0, 120)
|
setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL, 0, 120)
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,10 +1,15 @@
|
|||||||
package com.dano.test1
|
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.util.LanguageManager
|
||||||
|
import com.dano.test1.MainActivity
|
||||||
|
import com.dano.test1.MyApp
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import com.dano.test1.data.CompletedQuestionnaire
|
import com.dano.test1.data.CompletedQuestionnaire
|
||||||
|
import com.dano.test1.questionnaire.GlobalValues
|
||||||
|
import com.dano.test1.questionnaire.QuestionItem
|
||||||
|
|
||||||
class LoadButtonHandler(
|
class LoadButtonHandler(
|
||||||
private val activity: MainActivity,
|
private val activity: MainActivity,
|
||||||
@ -40,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) {
|
||||||
@ -80,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) {
|
||||||
@ -97,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) {
|
||||||
@ -117,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()
|
||||||
@ -1,12 +1,21 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.ui
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.ContentUris
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.pdf.PdfDocument
|
import android.graphics.pdf.PdfDocument
|
||||||
|
import android.provider.MediaStore
|
||||||
import android.util.Log
|
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.util.LanguageManager
|
||||||
|
import com.dano.test1.MainActivity
|
||||||
|
import com.dano.test1.MyApp
|
||||||
|
import com.dano.test1.questionnaire.GlobalValues
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
class SaveButtonHandler(
|
class SaveButtonHandler(
|
||||||
@ -35,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) {
|
||||||
@ -65,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("-")
|
||||||
@ -105,19 +114,19 @@ class SaveButtonHandler(
|
|||||||
val resolver = activity.contentResolver
|
val resolver = activity.contentResolver
|
||||||
|
|
||||||
val deleteIfExists: (String) -> Unit = { name ->
|
val deleteIfExists: (String) -> Unit = { name ->
|
||||||
val projection = arrayOf(android.provider.MediaStore.MediaColumns._ID)
|
val projection = arrayOf(MediaStore.MediaColumns._ID)
|
||||||
val selection = "${android.provider.MediaStore.MediaColumns.DISPLAY_NAME} = ?"
|
val selection = "${MediaStore.MediaColumns.DISPLAY_NAME} = ?"
|
||||||
val selectionArgs = arrayOf(name)
|
val selectionArgs = arrayOf(name)
|
||||||
val query = resolver.query(
|
val query = resolver.query(
|
||||||
android.provider.MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
||||||
projection, selection, selectionArgs, null
|
projection, selection, selectionArgs, null
|
||||||
)
|
)
|
||||||
query?.use { cursor ->
|
query?.use { cursor ->
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
val idColumn = cursor.getColumnIndexOrThrow(android.provider.MediaStore.MediaColumns._ID)
|
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)
|
||||||
val id = cursor.getLong(idColumn)
|
val id = cursor.getLong(idColumn)
|
||||||
val deleteUri = android.content.ContentUris.withAppendedId(
|
val deleteUri = ContentUris.withAppendedId(
|
||||||
android.provider.MediaStore.Downloads.EXTERNAL_CONTENT_URI, id
|
MediaStore.Downloads.EXTERNAL_CONTENT_URI, id
|
||||||
)
|
)
|
||||||
resolver.delete(deleteUri, null, null)
|
resolver.delete(deleteUri, null, null)
|
||||||
}
|
}
|
||||||
@ -129,20 +138,20 @@ class SaveButtonHandler(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val pdfUri = resolver.insert(
|
val pdfUri = resolver.insert(
|
||||||
android.provider.MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
||||||
android.content.ContentValues().apply {
|
ContentValues().apply {
|
||||||
put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, pdfFileName)
|
put(MediaStore.MediaColumns.DISPLAY_NAME, pdfFileName)
|
||||||
put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
|
put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
|
||||||
put(android.provider.MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
|
put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val csvUri = resolver.insert(
|
val csvUri = resolver.insert(
|
||||||
android.provider.MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
||||||
android.content.ContentValues().apply {
|
ContentValues().apply {
|
||||||
put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, csvFileName)
|
put(MediaStore.MediaColumns.DISPLAY_NAME, csvFileName)
|
||||||
put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "text/csv")
|
put(MediaStore.MediaColumns.MIME_TYPE, "text/csv")
|
||||||
put(android.provider.MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
|
put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -162,13 +171,13 @@ class SaveButtonHandler(
|
|||||||
Toast.makeText(activity, msg, Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, msg, Toast.LENGTH_LONG).show()
|
||||||
|
|
||||||
pdfUri?.let {
|
pdfUri?.let {
|
||||||
val intent = android.content.Intent(android.content.Intent.ACTION_VIEW).apply {
|
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||||
setDataAndType(it, "application/pdf")
|
setDataAndType(it, "application/pdf")
|
||||||
addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION or android.content.Intent.FLAG_ACTIVITY_NO_HISTORY)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NO_HISTORY)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
activity.startActivity(intent)
|
activity.startActivity(intent)
|
||||||
} catch (e: android.content.ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
val noViewer = LanguageManager.getText(languageIDProvider(), "no_pdf_viewer")
|
val noViewer = LanguageManager.getText(languageIDProvider(), "no_pdf_viewer")
|
||||||
Toast.makeText(activity, noViewer, Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, noViewer, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.util
|
||||||
|
|
||||||
|
import com.dano.test1.util.LanguageManager
|
||||||
|
|
||||||
object Countries {
|
object Countries {
|
||||||
fun getAllCountries(languageID: String): List<String> {
|
fun getAllCountries(languageID: String): List<String> {
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.util
|
||||||
|
|
||||||
import java.util.Calendar
|
import com.dano.test1.questionnaire.MAX_VALUE_AGE
|
||||||
|
import com.dano.test1.questionnaire.MAX_VALUE_YEAR
|
||||||
|
import com.dano.test1.ui.RHS_POINTS
|
||||||
|
|
||||||
object LanguageManager {
|
object LanguageManager {
|
||||||
fun getTextFormatted(languageId: String, key: String, vararg args: Any): String {
|
fun getTextFormatted(languageId: String, key: String, vararg args: Any): String {
|
||||||
@ -61,14 +63,14 @@ object LanguageManager {
|
|||||||
"once" to "einmal",
|
"once" to "einmal",
|
||||||
"year_after_2000" to "Das Jahr muss nach 2000 liegen!",
|
"year_after_2000" to "Das Jahr muss nach 2000 liegen!",
|
||||||
"year_after_departure" to "Das Jahr muss nach dem Verlassen des Herkunftslandes liegen!",
|
"year_after_departure" to "Das Jahr muss nach dem Verlassen des Herkunftslandes liegen!",
|
||||||
"year_max" to "Das Jahr muss kleiner oder gleich $MAX_VALUE_YEAR sein!",
|
"year_max" to "Das Jahr muss kleiner oder gleich ${MAX_VALUE_YEAR} sein!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Wichtig:</font></b> Die Daten können nach dem Abschluss nicht mehr verändert oder bearbeitet werden!",
|
"data_final_warning" to "<b><font color='#FF0000'>Wichtig:</font></b> Die Daten können nach dem Abschluss nicht mehr verändert oder bearbeitet werden!",
|
||||||
"multiple_times" to "mehrmals",
|
"multiple_times" to "mehrmals",
|
||||||
"more_than_15_years" to "mehr als 15 Jahre",
|
"more_than_15_years" to "mehr als 15 Jahre",
|
||||||
"no" to "Nein",
|
"no" to "Nein",
|
||||||
"no_answer" to "keine Angabe",
|
"no_answer" to "keine Angabe",
|
||||||
"other_country" to "anderes Land",
|
"other_country" to "anderes Land",
|
||||||
"value_must_be_less_equal_max" to "Der Wert muss kleiner oder gleich $MAX_VALUE_AGE sein!",
|
"value_must_be_less_equal_max" to "Der Wert muss kleiner oder gleich ${MAX_VALUE_AGE} sein!",
|
||||||
"value_between_1_and_15" to "Der Wert muss zwischen 1 und 15 liegen!",
|
"value_between_1_and_15" to "Der Wert muss zwischen 1 und 15 liegen!",
|
||||||
"invalid_month" to "Ungültige Monatsangabe!",
|
"invalid_month" to "Ungültige Monatsangabe!",
|
||||||
"invalid_year" to "Ungültige Jahresangabe!",
|
"invalid_year" to "Ungültige Jahresangabe!",
|
||||||
@ -438,14 +440,14 @@ object LanguageManager {
|
|||||||
"once" to "once",
|
"once" to "once",
|
||||||
"year_after_2000" to "The year must be after 2000!",
|
"year_after_2000" to "The year must be after 2000!",
|
||||||
"year_after_departure" to "The year must be after leaving the country of origin!",
|
"year_after_departure" to "The year must be after leaving the country of origin!",
|
||||||
"year_max" to "The year must be less than or equal to $MAX_VALUE_YEAR!",
|
"year_max" to "The year must be less than or equal to ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Important:</font></b> The data cannot be changed or edited after completion!",
|
"data_final_warning" to "<b><font color='#FF0000'>Important:</font></b> The data cannot be changed or edited after completion!",
|
||||||
"multiple_times" to "multiple times",
|
"multiple_times" to "multiple times",
|
||||||
"more_than_15_years" to "more than 15 years",
|
"more_than_15_years" to "more than 15 years",
|
||||||
"no" to "No",
|
"no" to "No",
|
||||||
"no_answer" to "No answer",
|
"no_answer" to "No answer",
|
||||||
"other_country" to "Other country",
|
"other_country" to "Other country",
|
||||||
"value_must_be_less_equal_max" to "The value must be less than or equal to $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "The value must be less than or equal to ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "The value must be between 1 and 15!",
|
"value_between_1_and_15" to "The value must be between 1 and 15!",
|
||||||
"invalid_month" to "Invalid month!",
|
"invalid_month" to "Invalid month!",
|
||||||
"invalid_year" to "Invalid year!",
|
"invalid_year" to "Invalid year!",
|
||||||
@ -814,14 +816,14 @@ object LanguageManager {
|
|||||||
"once" to "une fois",
|
"once" to "une fois",
|
||||||
"year_after_2000" to "L’année doit être après 2000 !",
|
"year_after_2000" to "L’année doit être après 2000 !",
|
||||||
"year_after_departure" to "L’année doit être après le départ du pays d’origine !",
|
"year_after_departure" to "L’année doit être après le départ du pays d’origine !",
|
||||||
"year_max" to "L’année doit être inférieure ou égale à $MAX_VALUE_YEAR !",
|
"year_max" to "L’année doit être inférieure ou égale à ${MAX_VALUE_YEAR} !",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Important :</font></b> Les données ne peuvent plus être modifiées ou éditées après la validation !",
|
"data_final_warning" to "<b><font color='#FF0000'>Important :</font></b> Les données ne peuvent plus être modifiées ou éditées après la validation !",
|
||||||
"multiple_times" to "plusieurs fois",
|
"multiple_times" to "plusieurs fois",
|
||||||
"more_than_15_years" to "plus de 15 ans",
|
"more_than_15_years" to "plus de 15 ans",
|
||||||
"no" to "Non",
|
"no" to "Non",
|
||||||
"no_answer" to "pas de réponse",
|
"no_answer" to "pas de réponse",
|
||||||
"other_country" to "autre pays",
|
"other_country" to "autre pays",
|
||||||
"value_must_be_less_equal_max" to "La valeur doit être inférieure ou égale à $MAX_VALUE_AGE !",
|
"value_must_be_less_equal_max" to "La valeur doit être inférieure ou égale à ${MAX_VALUE_AGE} !",
|
||||||
"value_between_1_and_15" to "La valeur doit être comprise entre 1 et 15 !",
|
"value_between_1_and_15" to "La valeur doit être comprise entre 1 et 15 !",
|
||||||
"invalid_month" to "Mois invalide !",
|
"invalid_month" to "Mois invalide !",
|
||||||
"invalid_year" to "Année invalide !",
|
"invalid_year" to "Année invalide !",
|
||||||
@ -1194,14 +1196,14 @@ object LanguageManager {
|
|||||||
"once" to "один раз",
|
"once" to "один раз",
|
||||||
"year_after_2000" to "Год должен быть после 2000!",
|
"year_after_2000" to "Год должен быть после 2000!",
|
||||||
"year_after_departure" to "Год должен быть после даты выезда из страны происхождения!",
|
"year_after_departure" to "Год должен быть после даты выезда из страны происхождения!",
|
||||||
"year_max" to "Год должен быть меньше или равен $MAX_VALUE_YEAR!",
|
"year_max" to "Год должен быть меньше или равен ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Внимание:</font></b> Данные нельзя изменять после завершения!",
|
"data_final_warning" to "<b><font color='#FF0000'>Внимание:</font></b> Данные нельзя изменять после завершения!",
|
||||||
"multiple_times" to "несколько раз",
|
"multiple_times" to "несколько раз",
|
||||||
"more_than_15_years" to "более 15 лет",
|
"more_than_15_years" to "более 15 лет",
|
||||||
"no" to "Нет",
|
"no" to "Нет",
|
||||||
"no_answer" to "без ответа",
|
"no_answer" to "без ответа",
|
||||||
"other_country" to "другая страна",
|
"other_country" to "другая страна",
|
||||||
"value_must_be_less_equal_max" to "Значение должно быть меньше или равно $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "Значение должно быть меньше или равно ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "Значение должно быть между 1 и 15!",
|
"value_between_1_and_15" to "Значение должно быть между 1 и 15!",
|
||||||
"invalid_month" to "Недопустимый месяц!",
|
"invalid_month" to "Недопустимый месяц!",
|
||||||
"invalid_year" to "Недопустимый год!",
|
"invalid_year" to "Недопустимый год!",
|
||||||
@ -1570,14 +1572,14 @@ object LanguageManager {
|
|||||||
"once" to "один раз",
|
"once" to "один раз",
|
||||||
"year_after_2000" to "Рік має бути після 2000!",
|
"year_after_2000" to "Рік має бути після 2000!",
|
||||||
"year_after_departure" to "Рік має бути після виїзду з країни походження!",
|
"year_after_departure" to "Рік має бути після виїзду з країни походження!",
|
||||||
"year_max" to "Рік має бути меншим або рівним $MAX_VALUE_YEAR!",
|
"year_max" to "Рік має бути меншим або рівним ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Важливо:</font></b> Дані після завершення не можна змінити або редагувати!",
|
"data_final_warning" to "<b><font color='#FF0000'>Важливо:</font></b> Дані після завершення не можна змінити або редагувати!",
|
||||||
"multiple_times" to "багато разів",
|
"multiple_times" to "багато разів",
|
||||||
"more_than_15_years" to "більше 15 років",
|
"more_than_15_years" to "більше 15 років",
|
||||||
"no" to "Ні",
|
"no" to "Ні",
|
||||||
"no_answer" to "немає відповіді",
|
"no_answer" to "немає відповіді",
|
||||||
"other_country" to "інша країна",
|
"other_country" to "інша країна",
|
||||||
"value_must_be_less_equal_max" to "Значення має бути меншим або рівним $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "Значення має бути меншим або рівним ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "Значення має бути від 1 до 15!",
|
"value_between_1_and_15" to "Значення має бути від 1 до 15!",
|
||||||
"invalid_month" to "Неправильний місяць!",
|
"invalid_month" to "Неправильний місяць!",
|
||||||
"invalid_year" to "Неправильний рік!",
|
"invalid_year" to "Неправильний рік!",
|
||||||
@ -1950,14 +1952,14 @@ object LanguageManager {
|
|||||||
"once" to "bir kez",
|
"once" to "bir kez",
|
||||||
"year_after_2000" to "Yıl 2000’den sonra olmalıdır!",
|
"year_after_2000" to "Yıl 2000’den sonra olmalıdır!",
|
||||||
"year_after_departure" to "Yıl, menşe ülkeyi terk ettikten sonra olmalıdır!",
|
"year_after_departure" to "Yıl, menşe ülkeyi terk ettikten sonra olmalıdır!",
|
||||||
"year_max" to "Yıl $MAX_VALUE_YEAR’den küçük veya ona eşit olmalıdır!",
|
"year_max" to "Yıl ${MAX_VALUE_YEAR}’den küçük veya ona eşit olmalıdır!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Önemli:</font></b> Veriler tamamlandıktan sonra değiştirilemez veya düzenlenemez!",
|
"data_final_warning" to "<b><font color='#FF0000'>Önemli:</font></b> Veriler tamamlandıktan sonra değiştirilemez veya düzenlenemez!",
|
||||||
"multiple_times" to "birden fazla kez",
|
"multiple_times" to "birden fazla kez",
|
||||||
"more_than_15_years" to "15 yıldan fazla",
|
"more_than_15_years" to "15 yıldan fazla",
|
||||||
"no" to "Hayır",
|
"no" to "Hayır",
|
||||||
"no_answer" to "Cevap yok",
|
"no_answer" to "Cevap yok",
|
||||||
"other_country" to "diğer ülke",
|
"other_country" to "diğer ülke",
|
||||||
"value_must_be_less_equal_max" to "Değer $MAX_VALUE_AGE’den küçük veya ona eşit olmalıdır!",
|
"value_must_be_less_equal_max" to "Değer ${MAX_VALUE_AGE}’den küçük veya ona eşit olmalıdır!",
|
||||||
"value_between_1_and_15" to "Değer 1 ile 15 arasında olmalıdır!",
|
"value_between_1_and_15" to "Değer 1 ile 15 arasında olmalıdır!",
|
||||||
"invalid_month" to "Geçersiz ay girişi!",
|
"invalid_month" to "Geçersiz ay girişi!",
|
||||||
"invalid_year" to "Geçersiz yıl girişi!",
|
"invalid_year" to "Geçersiz yıl girişi!",
|
||||||
@ -2330,14 +2332,14 @@ object LanguageManager {
|
|||||||
"once" to "jeden raz",
|
"once" to "jeden raz",
|
||||||
"year_after_2000" to "Rok musi być po 2000!",
|
"year_after_2000" to "Rok musi być po 2000!",
|
||||||
"year_after_departure" to "Rok musi być po opuszczeniu kraju pochodzenia!",
|
"year_after_departure" to "Rok musi być po opuszczeniu kraju pochodzenia!",
|
||||||
"year_max" to "Rok musi być mniejszy lub równy $MAX_VALUE_YEAR!",
|
"year_max" to "Rok musi być mniejszy lub równy ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Ważne:</font></b> Po zakończeniu dane nie mogą być zmienione ani edytowane!",
|
"data_final_warning" to "<b><font color='#FF0000'>Ważne:</font></b> Po zakończeniu dane nie mogą być zmienione ani edytowane!",
|
||||||
"multiple_times" to "kilka razy",
|
"multiple_times" to "kilka razy",
|
||||||
"more_than_15_years" to "więcej niż 15 lat",
|
"more_than_15_years" to "więcej niż 15 lat",
|
||||||
"no" to "Nie",
|
"no" to "Nie",
|
||||||
"no_answer" to "brak odpowiedzi",
|
"no_answer" to "brak odpowiedzi",
|
||||||
"other_country" to "inny kraj",
|
"other_country" to "inny kraj",
|
||||||
"value_must_be_less_equal_max" to "Wartość musi być mniejsza lub równa $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "Wartość musi być mniejsza lub równa ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "Wartość musi być między 1 a 15!",
|
"value_between_1_and_15" to "Wartość musi być między 1 a 15!",
|
||||||
"invalid_month" to "Nieprawidłowy miesiąc!",
|
"invalid_month" to "Nieprawidłowy miesiąc!",
|
||||||
"invalid_year" to "Nieprawidłowy rok!",
|
"invalid_year" to "Nieprawidłowy rok!",
|
||||||
@ -2710,14 +2712,14 @@ object LanguageManager {
|
|||||||
"once" to "مرة واحدة",
|
"once" to "مرة واحدة",
|
||||||
"year_after_2000" to "يجب أن تكون السنة بعد 2000!",
|
"year_after_2000" to "يجب أن تكون السنة بعد 2000!",
|
||||||
"year_after_departure" to "يجب أن تكون السنة بعد مغادرة بلد المنشأ!",
|
"year_after_departure" to "يجب أن تكون السنة بعد مغادرة بلد المنشأ!",
|
||||||
"year_max" to "يجب أن تكون السنة أقل من أو تساوي $MAX_VALUE_YEAR!",
|
"year_max" to "يجب أن تكون السنة أقل من أو تساوي ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>هام:</font></b> لا يمكن تعديل البيانات بعد الانتهاء!",
|
"data_final_warning" to "<b><font color='#FF0000'>هام:</font></b> لا يمكن تعديل البيانات بعد الانتهاء!",
|
||||||
"multiple_times" to "عدة مرات",
|
"multiple_times" to "عدة مرات",
|
||||||
"more_than_15_years" to "أكثر من 15 سنة",
|
"more_than_15_years" to "أكثر من 15 سنة",
|
||||||
"no" to "لا",
|
"no" to "لا",
|
||||||
"no_answer" to "لا يوجد إجابة",
|
"no_answer" to "لا يوجد إجابة",
|
||||||
"other_country" to "بلد آخر",
|
"other_country" to "بلد آخر",
|
||||||
"value_must_be_less_equal_max" to "يجب أن تكون القيمة أقل من أو تساوي $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "يجب أن تكون القيمة أقل من أو تساوي ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "يجب أن تكون القيمة بين 1 و15!",
|
"value_between_1_and_15" to "يجب أن تكون القيمة بين 1 و15!",
|
||||||
"invalid_month" to "شهر غير صالح!",
|
"invalid_month" to "شهر غير صالح!",
|
||||||
"invalid_year" to "سنة غير صالحة!",
|
"invalid_year" to "سنة غير صالحة!",
|
||||||
@ -3090,14 +3092,14 @@ object LanguageManager {
|
|||||||
"once" to "o dată",
|
"once" to "o dată",
|
||||||
"year_after_2000" to "Anul trebuie să fie după 2000!",
|
"year_after_2000" to "Anul trebuie să fie după 2000!",
|
||||||
"year_after_departure" to "Anul trebuie să fie după plecarea din țara de origine!",
|
"year_after_departure" to "Anul trebuie să fie după plecarea din țara de origine!",
|
||||||
"year_max" to "Anul trebuie să fie mai mic sau egal cu $MAX_VALUE_YEAR!",
|
"year_max" to "Anul trebuie să fie mai mic sau egal cu ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Important:</font></b> Datele nu mai pot fi modificate după finalizare!",
|
"data_final_warning" to "<b><font color='#FF0000'>Important:</font></b> Datele nu mai pot fi modificate după finalizare!",
|
||||||
"multiple_times" to "de mai multe ori",
|
"multiple_times" to "de mai multe ori",
|
||||||
"more_than_15_years" to "mai mult de 15 ani",
|
"more_than_15_years" to "mai mult de 15 ani",
|
||||||
"no" to "Nu",
|
"no" to "Nu",
|
||||||
"no_answer" to "fără răspuns",
|
"no_answer" to "fără răspuns",
|
||||||
"other_country" to "altă țară",
|
"other_country" to "altă țară",
|
||||||
"value_must_be_less_equal_max" to "Valoarea trebuie să fie mai mică sau egală cu $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "Valoarea trebuie să fie mai mică sau egală cu ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "Valoarea trebuie să fie între 1 și 15!",
|
"value_between_1_and_15" to "Valoarea trebuie să fie între 1 și 15!",
|
||||||
"invalid_month" to "Lună invalidă!",
|
"invalid_month" to "Lună invalidă!",
|
||||||
"invalid_year" to "An invalid!",
|
"invalid_year" to "An invalid!",
|
||||||
@ -3470,14 +3472,14 @@ object LanguageManager {
|
|||||||
"once" to "una vez",
|
"once" to "una vez",
|
||||||
"year_after_2000" to "¡El año debe ser posterior al 2000!",
|
"year_after_2000" to "¡El año debe ser posterior al 2000!",
|
||||||
"year_after_departure" to "¡El año debe ser posterior a la salida de su país de origen!",
|
"year_after_departure" to "¡El año debe ser posterior a la salida de su país de origen!",
|
||||||
"year_max" to "¡El año debe ser menor o igual que $MAX_VALUE_YEAR!",
|
"year_max" to "¡El año debe ser menor o igual que ${MAX_VALUE_YEAR}!",
|
||||||
"data_final_warning" to "<b><font color='#FF0000'>Importante:</font></b> Después de finalizar, los datos no podrán cambiarse o editarse.",
|
"data_final_warning" to "<b><font color='#FF0000'>Importante:</font></b> Después de finalizar, los datos no podrán cambiarse o editarse.",
|
||||||
"multiple_times" to "varias veces",
|
"multiple_times" to "varias veces",
|
||||||
"more_than_15_years" to "más de 15 años",
|
"more_than_15_years" to "más de 15 años",
|
||||||
"no" to "No",
|
"no" to "No",
|
||||||
"no_answer" to "sin respuesta",
|
"no_answer" to "sin respuesta",
|
||||||
"other_country" to "otro país",
|
"other_country" to "otro país",
|
||||||
"value_must_be_less_equal_max" to "¡El valor debe ser menor o igual que $MAX_VALUE_AGE!",
|
"value_must_be_less_equal_max" to "¡El valor debe ser menor o igual que ${MAX_VALUE_AGE}!",
|
||||||
"value_between_1_and_15" to "¡El valor debe estar entre 1 y 15!",
|
"value_between_1_and_15" to "¡El valor debe estar entre 1 y 15!",
|
||||||
"invalid_month" to "¡Mes no válido!",
|
"invalid_month" to "¡Mes no válido!",
|
||||||
"invalid_year" to "¡Año no válido!",
|
"invalid_year" to "¡Año no válido!",
|
||||||
@ -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
|
||||||
@ -1,11 +1,11 @@
|
|||||||
package com.dano.test1
|
package com.dano.test1.util
|
||||||
|
|
||||||
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")),
|
||||||
73
app/src/main/java/com/dano/test1/util/UiUtils.kt
Normal file
73
app/src/main/java/com/dano/test1/util/UiUtils.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user