Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-13 13:33:44 +03:00
parent 0ce9d71a2a
commit 402284dd27
17 changed files with 148 additions and 193 deletions

View file

@ -46,10 +46,11 @@ dependencies {
implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta4"
implementation "androidx.navigation:navigation-fragment-ktx:2.2.1"
implementation "androidx.navigation:navigation-ui-ktx:2.2.1"
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha01"
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
implementation "com.google.android.material:material:1.2.0-alpha05"
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.github.gbIxaHue:eu4d:0.3.7'
implementation 'com.github.gbIxaHue:eu4d:0.3.8'
}

View file

@ -59,8 +59,6 @@ class RvActionsVH(
containerDescription.visibility = if (wrapper.descriptionIsVisible) View.VISIBLE else View.GONE
}
override fun onDataBound(data: ActionType) {}
}
fun RecyclerView.ViewHolder.getString(@StringRes id: Int?, ifNull: String = ""): String {

View file

@ -8,6 +8,7 @@ import androidx.core.view.plusAssign
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.tangem.TangemSdk
import com.tangem.commands.Card
@ -28,7 +29,8 @@ import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
*/
abstract class BaseCardActionFragment : BaseFragment(), ActionView {
protected lateinit var itemContainer: ViewGroup
protected lateinit var swrLayout: SwipeRefreshLayout
protected lateinit var contentContainer: ViewGroup
protected lateinit var actionFab: FloatingActionButton
protected abstract val itemsManager: ItemsManager
@ -38,6 +40,8 @@ abstract class BaseCardActionFragment : BaseFragment(), ActionView {
private val paramsWidgetList = mutableListOf<ParameterWidget>()
override fun getLayoutId(): Int = R.layout.fg_base_action_layout
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(this, "onViewCreated")
@ -47,7 +51,7 @@ abstract class BaseCardActionFragment : BaseFragment(), ActionView {
actionVM.setCardManager(TangemSdk.init(requireActivity()))
actionVM.attachToPayload(mutableMapOf(PayloadKey.actionView to this as ActionView))
initFab()
initViews()
createWidgets {
widgetsWasCreated()
subscribeToViewModelChanges()
@ -57,11 +61,13 @@ abstract class BaseCardActionFragment : BaseFragment(), ActionView {
protected open fun widgetsWasCreated() {}
protected open fun bindViews() {
itemContainer = mainView.findViewById(R.id.ll_container)
swrLayout = mainView.findViewById(R.id.swr_layout)
contentContainer = mainView.findViewById(R.id.ll_content_container)
actionFab = mainView.findViewById(R.id.fab_action)
}
protected open fun initFab() {
protected open fun initViews() {
swrLayout.isEnabled = false
enableActionFab(false)
actionFab.setOnClickListener { actionVM.invokeMainAction() }
}
@ -70,7 +76,7 @@ abstract class BaseCardActionFragment : BaseFragment(), ActionView {
Log.d(this, "createWidgets")
actionVM.ldItemList.observe(viewLifecycleOwner, Observer { itemList ->
itemList.forEach { param ->
val widget = ParameterWidget(inflateParamView(itemContainer), param)
val widget = ParameterWidget(inflateParamView(contentContainer), param)
widget.onValueChanged = { id, value -> actionVM.userChangedItem(id, value) }
widget.onActionBtnClickListener = actionVM.getItemAction(param.id)
paramsWidgetList.add(widget)

View file

@ -1,6 +1,5 @@
package com.tangem.tangemtest.ucase.variants.depersonalize.ui
import com.tangem.tangemtest.R
import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager
import com.tangem.tangemtest.ucase.domain.paramsManager.managers.DepersonalizeItemsManager
import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment
@ -11,6 +10,4 @@ import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment
class DepersonalizeActionFragment : BaseCardActionFragment() {
override val itemsManager: ItemsManager by lazy { DepersonalizeItemsManager() }
override fun getLayoutId(): Int = R.layout.fg_depersonalize
}

View file

@ -4,7 +4,10 @@ import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import androidx.lifecycle.Observer
import androidx.transition.Fade
import androidx.transition.TransitionManager
import com.tangem.commands.Card
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.Id
@ -24,6 +27,8 @@ import com.tangem.tangemtest.ucase.variants.personalize.PersonalizationConfigSto
import com.tangem.tangemtest.ucase.variants.personalize.ui.widgets.PersonalizationItemBuilder
import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI
import ru.dev.gbixahue.eu4d.lib.android.global.threading.postWork
/**
[REDACTED_AUTHOR]
@ -32,17 +37,56 @@ class PersonalizationFragment : BaseCardActionFragment() {
override val itemsManager: ItemsManager by lazy { PersonalizationItemsManager(PersonalizationConfigStore(requireContext())) }
override fun getLayoutId(): Int = R.layout.fg_personalization
override fun getLayoutId(): Int = R.layout.fg_base_action_layout
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycle.addObserver(itemsManager as PersonalizationItemsManager)
}
override fun bindViews() {
super.bindViews()
swrLayout.isRefreshing = true
}
override fun initViews() {
actionFab.setOnClickListener { actionVM.invokeMainAction() }
}
override fun createWidgets(widgetCreatedCallback: () -> Unit) {
Log.d(this, "createWidgets")
val itemList = mutableListOf<Item>()
val maxDelay = 500
val timeStart = System.currentTimeMillis()
actionVM.ldItemList.observe(viewLifecycleOwner, Observer { list ->
Log.d(this, "ldBlockList size: ${list.size}")
itemList.addAll(list)
val llContainer = LinearLayout(requireContext()).apply { orientation = LinearLayout.VERTICAL }
postWork {
val builder = WidgetBuilder(PersonalizationItemBuilder())
itemList.forEach { builder.build(it, llContainer) }
actionVM.attachToPayload(mutableMapOf(
PayloadKey.actionView to this as ActionView,
PayloadKey.itemList to itemList
))
val timeEnd = System.currentTimeMillis()
val diff = timeEnd - timeStart
postUI(maxDelay - diff) {
TransitionManager.beginDelayedTransition(contentContainer, Fade())
contentContainer.addView(llContainer)
widgetCreatedCallback()
swrLayout.isRefreshing = false
swrLayout.isEnabled = false
}
}
})
}
override fun widgetsWasCreated() {
super.widgetsWasCreated()
val btnContainer = itemContainer.inflate<ViewGroup>(R.layout.view_simple_button)
val btnContainer = contentContainer.inflate<ViewGroup>(R.layout.view_simple_button)
val btn = btnContainer.findViewById<Button>(R.id.button)
val show = StringId("show")
@ -55,28 +99,7 @@ class PersonalizationFragment : BaseCardActionFragment() {
multiAction.state = if (it == show) hide else show
}
multiAction.performAction(hide)
itemContainer.addView(btnContainer)
}
override fun initFab() {
actionFab.setOnClickListener { actionVM.invokeMainAction() }
}
override fun createWidgets(widgetCreatedCallback: () -> Unit) {
Log.d(this, "createWidgets")
val itemList = mutableListOf<Item>()
actionVM.ldItemList.observe(viewLifecycleOwner, Observer { list ->
Log.d(this, "ldBlockList size: ${list.size}")
itemList.clear()
itemList.addAll(list)
itemList.forEach { WidgetBuilder(PersonalizationItemBuilder()).build(it, itemContainer) }
actionVM.attachToPayload(mutableMapOf(
PayloadKey.actionView to this as ActionView,
PayloadKey.itemList to itemList
))
widgetCreatedCallback()
})
contentContainer.addView(btnContainer)
}
override fun showSnackbar(id: Id, additionalHandler: ((Id) -> Int)?) {

View file

@ -23,7 +23,7 @@ open class ResponseFragment : BaseFragment() {
private val mainActivityVM: MainViewModel by activityViewModels()
private val selfVM: ResponseViewModel by viewModels()
private val itemContainer: ViewGroup by lazy { mainView.findViewById<LinearLayout>(R.id.ll_container) }
private val itemContainer: ViewGroup by lazy { mainView.findViewById<LinearLayout>(R.id.ll_content_container) }
override fun getLayoutId(): Int = R.layout.fg_card_response

View file

@ -1,10 +1,17 @@
package com.tangem.tangemtest.ucase.variants.scan.ui
import android.os.Bundle
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import com.tangem.commands.Card
import com.tangem.tangemtest.R
import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager
import com.tangem.tangemtest.ucase.domain.paramsManager.managers.ScanItemsManager
import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment
import ru.dev.gbixahue.eu4d.lib.android._android.views.dpToPx
/**
[REDACTED_AUTHOR]
@ -13,9 +20,30 @@ class ScanActionFragment : BaseCardActionFragment() {
override val itemsManager: ItemsManager by lazy { ScanItemsManager() }
override fun getLayoutId(): Int = R.layout.fg_action_card_scan
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun initFab() {
val howToUseView = createHowToUse()
contentContainer.layoutParams = FrameLayout.LayoutParams(-1, -1, Gravity.CENTER)
contentContainer.addView(howToUseView)
}
private fun createHowToUse(): View {
val fl = FrameLayout(requireContext())
fl.layoutParams = FrameLayout.LayoutParams(-1, -1, Gravity.CENTER)
val tv = TextView(requireContext()).apply {
val padding = dpToPx(16f).toInt()
setPadding(padding, 0, padding, 0)
gravity = Gravity.CENTER
setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
setText(R.string.htu_scan_action)
}
fl.addView(tv)
return fl
}
override fun initViews() {
swrLayout.isEnabled = false
actionFab.setOnClickListener { actionVM.invokeMainAction() }
}

View file

@ -1,6 +1,5 @@
package com.tangem.tangemtest.ucase.variants.sign.ui
import com.tangem.tangemtest.R
import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager
import com.tangem.tangemtest.ucase.domain.paramsManager.managers.SignItemsManager
import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment
@ -11,6 +10,4 @@ import com.tangem.tangemtest.ucase.ui.BaseCardActionFragment
class SignActionFragment : BaseCardActionFragment() {
override val itemsManager: ItemsManager by lazy { SignItemsManager() }
override fun getLayoutId(): Int = R.layout.fg_action_card_sign
}

View file

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<include layout="@layout/w_action_response_json" />
</LinearLayout>
</ScrollView>
<TextView
android:id="@+id/tv_screen_stub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textSize="18sp"
android:layout_margin="@dimen/def_double_indent"
android:text="@string/empty_screen_stub" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/def_indent"
android:layout_marginBottom="@dimen/def_double_indent"
android:src="@drawable/ic_nfc" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<include layout="@layout/w_action_response_json" />
</LinearLayout>
</ScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/def_indent"
android:layout_marginBottom="@dimen/def_double_indent"
android:src="@drawable/ic_nfc" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -5,29 +5,17 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<include layout="@layout/v_content_container" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/def_indent"
android:layout_marginBottom="@dimen/def_double_indent"
android:src="@drawable/ic_nfc"
app:layout_anchor="@id/scroll_view"
app:layout_anchor="@id/swr_layout"
app:layout_anchorGravity="bottom|end" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -10,7 +10,7 @@
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_container"
android:id="@+id/ll_content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

View file

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<include layout="@layout/w_action_response_json" />
</LinearLayout>
</ScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/def_indent"
android:layout_marginBottom="@dimen/def_double_indent"
android:src="@drawable/ic_nfc" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swr_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_content_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/item_header_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<LinearLayout
android:id="@+id/item_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<LinearLayout
android:id="@+id/item_footer_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>

View file

@ -57,25 +57,25 @@
android:id="@+id/nav_scan"
android:name="com.tangem.tangemtest.ucase.variants.scan.ui.ScanActionFragment"
android:label="@string/action_card_scan"
tools:layout="@layout/fg_action_card_scan" />
tools:layout="@layout/fg_base_action_layout" />
<fragment
android:id="@+id/nav_sign"
android:name="com.tangem.tangemtest.ucase.variants.sign.ui.SignActionFragment"
android:label="@string/action_card_sign"
tools:layout="@layout/fg_action_card_sign" />
tools:layout="@layout/fg_base_action_layout" />
<fragment
android:id="@+id/nav_personalize"
android:name="com.tangem.tangemtest.ucase.variants.personalize.ui.PersonalizationFragment"
android:label="@string/action_personalize"
tools:layout="@layout/fg_personalization" />
tools:layout="@layout/fg_base_action_layout" />
<fragment
android:id="@+id/nav_depersonalize"
android:name="com.tangem.tangemtest.ucase.variants.depersonalize.ui.DepersonalizeActionFragment"
android:label="@string/action_depersonalize"
tools:layout="@layout/fg_depersonalize" />
tools:layout="@layout/fg_base_action_layout" />
<fragment
android:id="@+id/nav_issuer_read_data"

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="empty_screen_stub">To read the card, press the button at the right bottom corner of the screen</string>
<!-- How to use -->
<string name="htu_scan_action">To read the card, press the button at the right bottom corner of the screen</string>
</resources>