Created shared UI utils + fixed NetworkUtils naming + minor refactoring

This commit is contained in:
2026-02-28 13:44:09 +01:00
parent e69be2ec6f
commit 092242f913
13 changed files with 112 additions and 301 deletions

View File

@ -2,9 +2,8 @@ package com.dano.test1.questionnaire
import android.view.View
import android.widget.*
import android.util.TypedValue
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 com.dano.test1.auth.TokenStore
@ -42,10 +41,10 @@ class HandlerClientCoachCode(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
setTextSizePercentOfScreenHeight(titleTextView, 0.03f)
setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
setTextSizePercentOfScreenHeight(clientCodeField, 0.025f)
setTextSizePercentOfScreenHeight(coachCodeField, 0.025f)
titleTextView.setTextSizePercentOfScreenHeight(0.03f)
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
clientCodeField.setTextSizePercentOfScreenHeight(0.025f)
coachCodeField.setTextSizePercentOfScreenHeight(0.025f)
// Client-Code: nur verwenden, wenn bereits geladen
val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE
@ -76,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) {
val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE

View File

@ -2,16 +2,13 @@ package com.dano.test1.questionnaire
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.*
import kotlinx.coroutines.*
import java.text.SimpleDateFormat
import java.util.*
import android.util.TypedValue
import android.view.Gravity
import androidx.core.widget.TextViewCompat
import android.widget.AbsListView
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.util.setupSpinner
import com.dano.test1.util.Month
import com.dano.test1.util.Months
import com.dano.test1.MyApp
@ -57,13 +54,11 @@ class HandlerDateSpinner(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
// Schriftgrößen pro Bildschirmhöhe
setTextSizePercentOfScreenHeight(textView, 0.03f) // oben
setTextSizePercentOfScreenHeight(questionTextView, 0.03f) // frage
setTextSizePercentOfScreenHeight(labelDay, 0.025f)
setTextSizePercentOfScreenHeight(labelMonth, 0.025f)
setTextSizePercentOfScreenHeight(labelYear, 0.025f)
//
textView.setTextSizePercentOfScreenHeight(0.03f)
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
labelDay.setTextSizePercentOfScreenHeight(0.025f)
labelMonth.setTextSizePercentOfScreenHeight(0.025f)
labelYear.setTextSizePercentOfScreenHeight(0.025f)
// gespeicherte Antwort (YYYY-MM-DD) lesen
val (savedYear, savedMonthIndex, savedDay) = question.question?.let {
@ -80,10 +75,9 @@ class HandlerDateSpinner(
?: months[today.get(Calendar.MONTH)]
val defaultYear = savedYear ?: today.get(Calendar.YEAR)
// Spinner responsiv aufsetzen (Schrift + Zeilenhöhe ohne Abschneiden)
setupSpinner(spinnerDay, days, defaultDay)
setupSpinner(spinnerMonth, months, defaultMonth)
setupSpinner(spinnerYear, years, defaultYear)
spinnerDay.setupSpinner(days, defaultDay)
spinnerMonth.setupSpinner(months, defaultMonth)
spinnerYear.setupSpinner(years, defaultYear)
// DB-Abfrage, falls noch nicht im answers-Map
val answerMapKey = question.question ?: (question.id ?: "")
@ -213,71 +207,4 @@ class HandlerDateSpinner(
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 Gravity.HORIZONTAL_GRAVITY_MASK) or Gravity.CENTER_VERTICAL
tv.setPadding(tv.paddingLeft, vPadPx, tv.paddingRight, vPadPx)
tv.minHeight = rowHeight
tv.isSingleLine = true
if (forceHeight) {
val lp = tv.layoutParams
if (lp == null || lp.height <= 0) {
tv.layoutParams = AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, rowHeight
)
} else {
lp.height = rowHeight
}
}
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val v = super.getView(position, convertView, parent) as TextView
styleRow(v, forceHeight = false)
return v
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
val v = super.getDropDownView(position, convertView, parent) as TextView
styleRow(v, forceHeight = true)
return v
}
}
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
spinner.setPadding(spinner.paddingLeft, vPadPx, spinner.paddingRight, vPadPx)
spinner.minimumHeight = rowHeight
spinner.requestLayout()
defaultSelection?.let {
val index = items.indexOf(it)
if (index >= 0) spinner.setSelection(index)
}
}
}

View File

@ -5,8 +5,8 @@ import android.util.TypedValue
import android.view.Gravity
import android.view.View
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.*
@ -70,8 +70,8 @@ class HandlerGlassScaleQuestion(
titleTv.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
questionTv.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
setTextSizePercentOfScreenHeight(titleTv, 0.03f)
setTextSizePercentOfScreenHeight(questionTv, 0.03f)
titleTv.setTextSizePercentOfScreenHeight(0.03f)
questionTv.setTextSizePercentOfScreenHeight(0.03f)
// Header Icons
val header = layout.findViewById<LinearLayout>(R.id.glass_header)
@ -153,7 +153,7 @@ class HandlerGlassScaleQuestion(
text = LanguageManager.getText(languageID, symptomKey)
layoutParams = TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 4f)
setPadding(4, 16, 4, 16)
setTextSizePercentOfScreenHeight(this, 0.022f)
setTextSizePercentOfScreenHeight(0.022f)
}
row.addView(symptomText)
@ -280,10 +280,4 @@ class HandlerGlassScaleQuestion(
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)
}
}

View File

@ -5,9 +5,9 @@ import android.widget.*
import android.text.Html
import kotlinx.coroutines.*
import android.util.TypedValue
import android.widget.TextView
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
@ -60,9 +60,8 @@ class HandlerLastPage(
finishBtn.isAllCaps = false
applyResponsiveTextSizing(finishBtn)
// Überschriften responsiv skalieren (wie zuvor)
setTextSizePercentOfScreenHeight(titleTv, 0.03f)
setTextSizePercentOfScreenHeight(questionTv, 0.03f)
titleTv.setTextSizePercentOfScreenHeight(0.03f)
questionTv.setTextSizePercentOfScreenHeight(0.03f)
// Buttons
prevBtn.setOnClickListener { goToPreviousQuestion() }
@ -131,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 =
answers.filterKeys { it.endsWith("_points") }
.values.mapNotNull { it as? Int }

View File

@ -7,6 +7,7 @@ import kotlinx.coroutines.*
import android.util.TypedValue
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
@ -40,9 +41,8 @@ class HandlerMultiCheckboxQuestion(
questionTextView.text = this.question.textKey?.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)
setTextSizePercentOfScreenHeight(questionTextView, 0.03f) // Überschrift
setTextSizePercentOfScreenHeight(questionTitle, 0.03f) // Frage
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
questionTitle.setTextSizePercentOfScreenHeight(0.03f)
container.removeAllViews()
@ -207,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)
}
}

View File

@ -5,9 +5,8 @@ import android.view.View
import android.text.Html
import android.widget.*
import kotlinx.coroutines.*
import android.util.TypedValue
import androidx.core.widget.TextViewCompat // <— hinzugefügt
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MyApp
import com.dano.test1.R
@ -44,11 +43,8 @@ class HandlerRadioQuestion(
Html.fromHtml(LanguageManager.getText(languageID, it), Html.FROM_HTML_MODE_LEGACY)
} ?: ""
//
// Titel/Frage: 3% der Bildschirmhöhe
setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
setTextSizePercentOfScreenHeight(questionTitle, 0.03f)
// ===================================================
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
questionTitle.setTextSizePercentOfScreenHeight(0.03f)
radioGroup.removeAllViews()
@ -57,8 +53,7 @@ class HandlerRadioQuestion(
text = LanguageManager.getText(languageID, option.key)
tag = option.key
// RadioButton-Text analog zu EditTexts: 2.5% der Bildschirmhöhe
setTextSizePercentOfScreenHeight(this, 0.025f)
setTextSizePercentOfScreenHeight(0.025f)
layoutParams = RadioGroup.LayoutParams(
RadioGroup.LayoutParams.MATCH_PARENT,
@ -140,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) {
question.question?.let { questionKey ->
val savedAnswer = answers[questionKey] as? String

View File

@ -2,14 +2,11 @@ package com.dano.test1.questionnaire
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.*
import kotlinx.coroutines.*
import android.util.TypedValue
import android.view.Gravity
import android.widget.TextView
import androidx.core.widget.TextViewCompat
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.util.setupSpinner
import com.dano.test1.MyApp
import com.dano.test1.R
import com.dano.test1.util.Countries
@ -47,17 +44,15 @@ class HandlerStringSpinner(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
// Textgrößen prozentual zur Bildschirmhöhe (wie im HandlerRadioQuestion)
setTextSizePercentOfScreenHeight(textView, 0.03f)
setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
textView.setTextSizePercentOfScreenHeight(0.03f)
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
val options = buildOptionsList()
// vorhandene Auswahl (falls vorhanden)
val savedSelection = question.question?.let { answers[it] as? String }
// Spinner aufsetzen
setupSpinner(spinner, options, savedSelection)
spinner.setupSpinner(options, savedSelection)
// Falls noch keine Antwort im Map: aus DB laden
val answerMapKey = question.question ?: (question.id ?: "")
@ -124,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 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) // 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)
}
}
}

View File

@ -2,13 +2,11 @@ package com.dano.test1.questionnaire
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.*
import kotlinx.coroutines.*
import android.util.TypedValue
import android.view.Gravity
import androidx.core.widget.TextViewCompat // <- NEU
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.util.setupSpinner
import com.dano.test1.MyApp
import com.dano.test1.R
@ -47,10 +45,8 @@ class HandlerValueSpinner(
questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
// Schriftgrößen wie im HandlerRadioQuestion
// Titel/Frage: 3% der Bildschirmhöhe
setTextSizePercentOfScreenHeight(textView, 0.03f)
setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
textView.setTextSizePercentOfScreenHeight(0.03f)
questionTextView.setTextSizePercentOfScreenHeight(0.03f)
val prompt = LanguageManager.getText(languageID, "choose_answer")
val spinnerItems: List<String> = listOf(prompt) + if (question.range != null) {
@ -60,7 +56,7 @@ class HandlerValueSpinner(
}
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
val answerMapKey = question.question ?: (question.id ?: "")
@ -131,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 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) // 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)
}
}
}

View File

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