Updated on 2026-08-14
This commit is contained in:
parent
9056c31bb6
commit
acd023b2f5
8 changed files with 106 additions and 51 deletions
|
|
@ -13,8 +13,10 @@ typealias SafeValueChange<V> = (V) -> Unit
|
|||
|
||||
class KeyValue(val key: String, val value: Any)
|
||||
|
||||
class ViewState {
|
||||
var isHiddenField = false
|
||||
class ViewState(
|
||||
var isHidden: Boolean = false,
|
||||
var backgroundColor: Int? = -1
|
||||
) {
|
||||
|
||||
var descriptionVisibility: Int = 0x00000008
|
||||
set(value) {
|
||||
|
|
@ -34,9 +36,11 @@ interface ItemViewModel : PayloadHolder {
|
|||
fun updateDataByView(data: Any?)
|
||||
}
|
||||
|
||||
open class BaseItemViewModel(value: Any? = null) : ItemViewModel {
|
||||
open class BaseItemViewModel(
|
||||
value: Any? = null,
|
||||
override val viewState: ViewState = ViewState()
|
||||
) : ItemViewModel {
|
||||
|
||||
override val viewState: ViewState = ViewState()
|
||||
override val payload: Payload = mutableMapOf()
|
||||
|
||||
// Don't update it directly from a View. Use for it updateDataByView()
|
||||
|
|
@ -75,6 +79,7 @@ open class BaseItemViewModel(value: Any? = null) : ItemViewModel {
|
|||
}
|
||||
|
||||
class ListViewModel(
|
||||
val itemList: List<KeyValue>,
|
||||
var selectedItem: Any?,
|
||||
val itemList: List<KeyValue>
|
||||
override val viewState: ViewState = ViewState()
|
||||
) : BaseItemViewModel(selectedItem)
|
||||
|
|
@ -1,25 +1,39 @@
|
|||
package com.tangem.tangemtest._arch.structure.impl
|
||||
|
||||
import com.tangem.tangemtest._arch.structure.Id
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.BaseItem
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.BaseItemViewModel
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.KeyValue
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.ListViewModel
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.*
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
|
||||
open class TypedItem<D>(id: Id, value: D? = null) : BaseItem(id, BaseItemViewModel(value)) {
|
||||
open class TypedItem<D>(id: Id, viewModel: ItemViewModel) : BaseItem(id, viewModel) {
|
||||
open fun getTypedData(): D? = viewModel.data as? D
|
||||
}
|
||||
|
||||
class TextItem(id: Id, value: String? = null) : TypedItem<String>(id, value)
|
||||
class NumberItem(id: Id, value: Number? = null) : TypedItem<Number>(id, value)
|
||||
class BoolItem(id: Id, value: Boolean? = null) : TypedItem<Boolean>(id, value)
|
||||
class TextItem(id: Id, viewModel: ItemViewModel) : TypedItem<String>(id, viewModel) {
|
||||
constructor(id: Id, value: String? = null, viewState: ViewState = ViewState())
|
||||
: this(id, BaseItemViewModel(value, viewState))
|
||||
}
|
||||
|
||||
class EditTextItem(id: Id, value: String? = null) : TypedItem<String>(id, value)
|
||||
class NumberItem(id: Id, viewModel: ItemViewModel) : TypedItem<Number>(id, viewModel) {
|
||||
constructor(id: Id, value: Number? = null, viewState: ViewState = ViewState())
|
||||
: this(id, BaseItemViewModel(value, viewState))
|
||||
}
|
||||
|
||||
class SpinnerItem(id: Id, value: List<KeyValue>, selectedValue: Any?)
|
||||
: TypedItem<ListViewModel>(id, ListViewModel(selectedValue, value)
|
||||
)
|
||||
class BoolItem(id: Id, viewModel: ItemViewModel) : TypedItem<Boolean>(id, viewModel) {
|
||||
constructor(id: Id, value: Boolean? = null, viewState: ViewState = ViewState())
|
||||
: this(id, BaseItemViewModel(value, viewState))
|
||||
}
|
||||
|
||||
|
||||
class EditTextItem(id: Id, viewModel: ItemViewModel) : TypedItem<String>(id, viewModel) {
|
||||
constructor(id: Id, value: String? = null, viewState: ViewState = ViewState())
|
||||
: this(id, BaseItemViewModel(value, viewState))
|
||||
}
|
||||
|
||||
|
||||
class SpinnerItem(id: Id, viewModel: ListViewModel) : TypedItem<ListViewModel>(id, viewModel) {
|
||||
constructor(id: Id, list: List<KeyValue>, selectedValue: Any?, viewState: ViewState = ViewState())
|
||||
: this(id, ListViewModel(list, selectedValue, viewState))
|
||||
}
|
||||
|
|
@ -1,12 +1,16 @@
|
|||
package com.tangem.tangemtest._arch.widget.abstraction
|
||||
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.ColorRes
|
||||
import com.tangem.tangemtest.R
|
||||
import com.tangem.tangemtest._arch.structure.StringId
|
||||
import com.tangem.tangemtest._arch.structure.StringResId
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.Item
|
||||
import ru.dev.gbixahue.eu4d.lib.android._android.views.colorFrom
|
||||
import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder
|
||||
|
||||
/**
|
||||
|
|
@ -17,6 +21,7 @@ interface ViewWidget : LayoutHolder {
|
|||
var item: Item
|
||||
|
||||
fun getName(): String
|
||||
fun setBackgroundColor(@ColorRes colorId: Int?)
|
||||
}
|
||||
|
||||
abstract class BaseViewWidget(
|
||||
|
|
@ -25,10 +30,14 @@ abstract class BaseViewWidget(
|
|||
) : ViewWidget {
|
||||
|
||||
override val view: View = inflate(getLayoutId(), parent)
|
||||
private var defaultBackground: Drawable = view.background
|
||||
|
||||
|
||||
init {
|
||||
if (item.viewModel.viewState.isHiddenField) {
|
||||
if (item.viewModel.viewState.isHidden) {
|
||||
view.visibility = View.GONE
|
||||
} else {
|
||||
setBackgroundColor(item.viewModel.viewState.backgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -39,6 +48,15 @@ abstract class BaseViewWidget(
|
|||
else -> view.resources.getString(R.string.unknown)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setBackgroundColor(colorId: Int?) {
|
||||
val background = when {
|
||||
colorId == null -> null
|
||||
colorId == -1 -> defaultBackground
|
||||
else -> ColorDrawable(view.colorFrom(colorId))
|
||||
}
|
||||
view.background = background
|
||||
}
|
||||
}
|
||||
|
||||
internal fun inflate(id: Int, parent: ViewGroup): View {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ class PersonalizationConfigToItems : ModelToItems<PersonalizationConfig> {
|
|||
blocList.add(pins())
|
||||
blocList.iterate {
|
||||
if (itemTypes.hiddenList.contains(it.id)) {
|
||||
it.viewModel.viewState.isHiddenField = true
|
||||
it.viewModel.viewState.isHidden = true
|
||||
}
|
||||
}
|
||||
return blocList
|
||||
|
|
|
|||
|
|
@ -18,41 +18,41 @@ import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf
|
|||
*/
|
||||
class SpinnerWidget(
|
||||
parent: ViewGroup,
|
||||
private val typedItem: SpinnerItem
|
||||
typedItem: SpinnerItem
|
||||
) : DescriptionWidget(parent, typedItem) {
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.w_personalize_item_spinner
|
||||
|
||||
private val data: ListViewModel = typedItem.getTypedData()!!
|
||||
private val viewModel: ListViewModel = typedItem.viewModel as ListViewModel
|
||||
|
||||
private val spItem = view.findViewById<Spinner>(R.id.sp_item)
|
||||
private val spAdapter = SpItemAdapter(data.itemList)
|
||||
private val spinner = view.findViewById<Spinner>(R.id.sp_item)
|
||||
private val spAdapter = SpItemAdapter(viewModel.itemList)
|
||||
|
||||
private val onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
data.selectedItem = data.itemList[position].value
|
||||
typedItem.viewModel.updateDataByView(data)
|
||||
viewModel.selectedItem = viewModel.itemList[position].value
|
||||
item.viewModel.updateDataByView(viewModel)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
val name = view.findViewById<TextView>(R.id.tv_name)
|
||||
name.text = getName()
|
||||
spItem.adapter = spAdapter
|
||||
spAdapter.getItemPosition(stringOf(data.selectedItem))?.let {
|
||||
spItem.setSelection(it)
|
||||
spinner.adapter = spAdapter
|
||||
spAdapter.getItemPosition(stringOf(viewModel.selectedItem))?.let {
|
||||
spinner.setSelection(it)
|
||||
}
|
||||
spItem.onItemSelectedListener = onItemSelectedListener
|
||||
typedItem.viewModel.onDataUpdated = {
|
||||
spinner.onItemSelectedListener = onItemSelectedListener
|
||||
item.viewModel.onDataUpdated = {
|
||||
val selectedItem = it as? String
|
||||
spItem.onItemSelectedListener = null
|
||||
data.itemList.firstOrNull { item -> item.value == selectedItem }?.let { keyValue ->
|
||||
val position = data.itemList.indexOf(keyValue)
|
||||
spItem.setSelection(position)
|
||||
spinner.onItemSelectedListener = null
|
||||
viewModel.itemList.firstOrNull { item -> item.value == selectedItem }?.let { keyValue ->
|
||||
val position = viewModel.itemList.indexOf(keyValue)
|
||||
spinner.setSelection(position)
|
||||
}
|
||||
spItem.onItemSelectedListener = onItemSelectedListener
|
||||
spinner.onItemSelectedListener = onItemSelectedListener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
package com.tangem.tangemtest.ucase.variants.responses.converter
|
||||
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.CardData
|
||||
import com.tangem.commands.Settings
|
||||
import com.tangem.commands.SettingsMask
|
||||
import com.tangem.tangemtest.R
|
||||
import com.tangem.tangemtest._arch.structure.Id
|
||||
import com.tangem.tangemtest._arch.structure.StringId
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.Item
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.ItemGroup
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.SimpleItemGroup
|
||||
import com.tangem.tangemtest._arch.structure.abstraction.*
|
||||
import com.tangem.tangemtest._arch.structure.impl.BoolItem
|
||||
import com.tangem.tangemtest._arch.structure.impl.TextItem
|
||||
import com.tangem.tangemtest.ucase.variants.personalize.BlockId
|
||||
|
|
@ -26,11 +25,26 @@ class CardConverter : ModelToItems<Card> {
|
|||
// itemList.add(TextItem(Additional.JSON_INCOMING, holder.gson.toJson(from)))
|
||||
|
||||
itemList.add(simpleFields(from))
|
||||
itemList.add(cardData(from))
|
||||
itemList.add(cardData(from.cardData))
|
||||
itemList.add(settingsMask(from.settingsMask))
|
||||
hideEmptyNullFields(itemList)
|
||||
|
||||
return itemList
|
||||
}
|
||||
|
||||
private fun hideEmptyNullFields(itemList: MutableList<Item>) {
|
||||
itemList.iterate {
|
||||
val data = it.getData<Any?>()
|
||||
val isHidden = if (data == null) true
|
||||
else when (data) {
|
||||
is String -> data.isEmpty()
|
||||
else -> false
|
||||
}
|
||||
|
||||
if (isHidden) it.viewModel.viewState.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun simpleFields(from: Card): Item {
|
||||
val group = createGroup(BlockId.Common)
|
||||
group.addItem(TextItem(CardId.cardId, from.cardId))
|
||||
|
|
@ -55,9 +69,11 @@ class CardConverter : ModelToItems<Card> {
|
|||
return group
|
||||
}
|
||||
|
||||
private fun cardData(from: Card): Item {
|
||||
val group = createGroup(BlockId.Common)
|
||||
val data = from.cardData ?: return group
|
||||
private fun cardData(from: CardData?): Item {
|
||||
val group = createGroup(BlockId.Common, R.color.group_card_data)
|
||||
val data = from ?: return group
|
||||
|
||||
// group.addItem(TextItem(StringResId(R.string.response_card_card_data)))
|
||||
group.addItem(TextItem(CardDataId.batchId, data.batchId))
|
||||
// Format: Year (2 bytes) | Month (1 byte) | Day (1 byte)
|
||||
group.addItem(TextItem(CardDataId.manufactureDateTime, stringOf(data.manufactureDateTime)))
|
||||
|
|
@ -73,12 +89,16 @@ class CardConverter : ModelToItems<Card> {
|
|||
}
|
||||
|
||||
private fun settingsMask(from: SettingsMask?): Item {
|
||||
val group = createGroup(CardId.settingsMask)
|
||||
val group = createGroup(CardId.settingsMask, R.color.group_signing_method)
|
||||
val data = from ?: return group
|
||||
|
||||
// group.addItem(TextItem(StringResId(R.string.response_card_settings_mask)))
|
||||
Settings.values().forEach { group.addItem(BoolItem(StringId(it.name), data.contains(it))) }
|
||||
return group
|
||||
}
|
||||
|
||||
private fun createGroup(id: Id): ItemGroup = SimpleItemGroup(id).apply { addItem(TextItem(id)) }
|
||||
private fun createGroup(id: Id, colorId: Int? = null): ItemGroup {
|
||||
return if (colorId == null) SimpleItemGroup(id)
|
||||
else SimpleItemGroup(id, BaseItemViewModel(viewState = ViewState(backgroundColor = colorId)))
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.tangem.tangemtest.ucase.variants.responses.ui.widget
|
|||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import com.tangem.tangemtest.R
|
||||
|
|
@ -29,11 +28,6 @@ class ResponseTextWidget(
|
|||
|
||||
private fun initWidgets() {
|
||||
val data = typedItem.getData() as? String
|
||||
if (data == null || data.isEmpty()) {
|
||||
view.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
tvName.text = getName()
|
||||
tvValue.text = data
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@
|
|||
<color name="field_content">#303030</color>
|
||||
<color name="field_description">@color/field_info</color>
|
||||
|
||||
<color name="group_card_data">#D7E4F3</color>
|
||||
<color name="group_signing_method">#D7F3E6</color>
|
||||
|
||||
|
||||
<color name="switchTrack">#C6C6C6</color>
|
||||
<color name="switchTrackActive">#FFE391</color>
|
||||
<color name="switchThumb">#FFFFFF</color>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue