diff options
author | Torsten Grote <t@grobox.de> | 2020-09-03 10:01:11 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-09-03 10:41:20 -0300 |
commit | 126b0710dda4546dc3337df1bee886f5f4657674 (patch) | |
tree | 4b0ff37cf85805f4602cb92a47d3984282cdf384 | |
parent | 74b139473b395371ee487b9595627adcb85e78e9 (diff) | |
download | taler-android-126b0710dda4546dc3337df1bee886f5f4657674.tar.gz taler-android-126b0710dda4546dc3337df1bee886f5f4657674.tar.bz2 taler-android-126b0710dda4546dc3337df1bee886f5f4657674.zip |
[pos] migrate to view binding
14 files changed, 177 insertions, 152 deletions
diff --git a/merchant-terminal/build.gradle b/merchant-terminal/build.gradle index f7bbc1c..df8cee5 100644 --- a/merchant-terminal/build.gradle +++ b/merchant-terminal/build.gradle @@ -1,7 +1,6 @@ plugins { id 'com.android.application' id 'kotlin-android' - id 'kotlin-android-extensions' id 'kotlinx-serialization' id 'androidx.navigation.safeargs.kotlin' } @@ -13,7 +12,7 @@ android { defaultConfig { applicationId "net.taler.merchantpos" - minSdkVersion 26 + minSdkVersion 24 targetSdkVersion 29 versionCode 1 versionName "1.0" @@ -40,6 +39,10 @@ android { jvmTarget = "1.8" } + buildFeatures { + viewBinding = true + } + testOptions { unitTests { includeAndroidResources = true diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt index 533c540..47da74e 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt @@ -28,21 +28,20 @@ import android.widget.Toast.LENGTH_SHORT import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.view.GravityCompat.START -import androidx.lifecycle.Observer import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupWithNavController import com.google.android.material.navigation.NavigationView.OnNavigationItemSelectedListener -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.app_bar_main.* import net.taler.common.NfcManager +import net.taler.merchantpos.databinding.ActivityMainBinding class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener { private val model: MainViewModel by viewModels() private val nfcManager = NfcManager() + private lateinit var ui: ActivityMainBinding private lateinit var nav: NavController private var reallyExit = false @@ -53,9 +52,10 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + ui = ActivityMainBinding.inflate(layoutInflater) + setContentView(ui.root) - model.paymentManager.payment.observe(this, Observer { payment -> + model.paymentManager.payment.observe(this, { payment -> payment?.talerPayUri?.let { nfcManager.setTagString(it) } @@ -65,12 +65,12 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener { supportFragmentManager.findFragmentById(R.id.navHostFragment) as NavHostFragment nav = navHostFragment.navController - nav_view.setupWithNavController(nav) - nav_view.setNavigationItemSelectedListener(this) + ui.navView.setupWithNavController(nav) + ui.navView.setNavigationItemSelectedListener(this) - setSupportActionBar(toolbar) - val appBarConfiguration = AppBarConfiguration(nav.graph, drawer_layout) - toolbar.setupWithNavController(nav, appBarConfiguration) + setSupportActionBar(ui.main.toolbar) + val appBarConfiguration = AppBarConfiguration(nav.graph, ui.drawerLayout) + ui.main.toolbar.setupWithNavController(nav, appBarConfiguration) } override fun onStart() { @@ -99,14 +99,14 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener { R.id.nav_history -> nav.navigate(R.id.action_global_merchantHistory) R.id.nav_settings -> nav.navigate(R.id.action_global_merchantSettings) } - drawer_layout.closeDrawer(START) + ui.drawerLayout.closeDrawer(START) return true } override fun onBackPressed() { val currentDestination = nav.currentDestination?.id - if (drawer_layout.isDrawerOpen(START)) { - drawer_layout.closeDrawer(START) + if (ui.drawerLayout.isDrawerOpen(START)) { + ui.drawerLayout.closeDrawer(START) } else if (currentDestination == R.id.nav_settings && !model.configManager.config.isValid()) { // we are in the configuration screen and need a config to continue val intent = Intent(ACTION_MAIN).apply { diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt index 8231052..87004d8 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt @@ -27,20 +27,23 @@ import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT import com.google.android.material.snackbar.Snackbar import net.taler.common.navigate import net.taler.merchantpos.MainViewModel -import net.taler.merchantpos.R import net.taler.merchantpos.config.ConfigFetcherFragmentDirections.Companion.actionConfigFetcherToMerchantSettings import net.taler.merchantpos.config.ConfigFetcherFragmentDirections.Companion.actionConfigFetcherToOrder +import net.taler.merchantpos.databinding.FragmentConfigFetcherBinding class ConfigFetcherFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val configManager by lazy { model.configManager } + private lateinit var ui: FragmentConfigFetcherBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_config_fetcher, container, false) + ui = FragmentConfigFetcherBinding.inflate(inflater) + return ui.root } override fun onActivityCreated(savedInstanceState: Bundle?) { diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt index daddbff..c31eb61 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt @@ -30,11 +30,11 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_merchant_config.* import net.taler.common.navigate import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R import net.taler.merchantpos.config.ConfigFragmentDirections.Companion.actionSettingsToOrder +import net.taler.merchantpos.databinding.FragmentMerchantConfigBinding import net.taler.merchantpos.topSnackbar /** @@ -45,86 +45,89 @@ class ConfigFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val configManager by lazy { model.configManager } + private lateinit var ui: FragmentMerchantConfigBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_merchant_config, container, false) + ui = FragmentMerchantConfigBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - configUrlView.editText!!.setOnFocusChangeListener { _, hasFocus -> + ui.configUrlView.editText!!.setOnFocusChangeListener { _, hasFocus -> if (!hasFocus) checkForUrlCredentials() } - okButton.setOnClickListener { + ui.okButton.setOnClickListener { checkForUrlCredentials() - val inputUrl = configUrlView.editText!!.text + val inputUrl = ui.configUrlView.editText!!.text val url = if (inputUrl.startsWith("http")) { inputUrl.toString() } else { - "https://$inputUrl".also { configUrlView.editText!!.setText(it) } + "https://$inputUrl".also { ui.configUrlView.editText!!.setText(it) } } - progressBar.visibility = VISIBLE - okButton.visibility = INVISIBLE + ui.progressBar.visibility = VISIBLE + ui.okButton.visibility = INVISIBLE val config = Config( configUrl = url, - username = usernameView.editText!!.text.toString(), - password = passwordView.editText!!.text.toString() + username = ui.usernameView.editText!!.text.toString(), + password = ui.passwordView.editText!!.text.toString() ) - configManager.fetchConfig(config, true, savePasswordCheckBox.isChecked) + configManager.fetchConfig(config, true, ui.savePasswordCheckBox.isChecked) configManager.configUpdateResult.observe(viewLifecycleOwner, Observer { result -> if (onConfigUpdate(result)) { configManager.configUpdateResult.removeObservers(viewLifecycleOwner) } }) } - forgetPasswordButton.setOnClickListener { + ui.forgetPasswordButton.setOnClickListener { configManager.forgetPassword() - passwordView.editText!!.text = null - forgetPasswordButton.visibility = GONE + ui.passwordView.editText!!.text = null + ui.forgetPasswordButton.visibility = GONE } - configDocsView.movementMethod = LinkMovementMethod.getInstance() + ui.configDocsView.movementMethod = LinkMovementMethod.getInstance() updateView(savedInstanceState == null) } override fun onStart() { super.onStart() // focus password if this is the only empty field - if (passwordView.editText!!.text.isBlank() - && !configUrlView.editText!!.text.isBlank() - && !usernameView.editText!!.text.isBlank() + if (ui.passwordView.editText!!.text.isBlank() + && !ui.configUrlView.editText!!.text.isBlank() + && !ui.usernameView.editText!!.text.isBlank() ) { - passwordView.requestFocus() + ui.passwordView.requestFocus() } } private fun updateView(isInitialization: Boolean = false) { val config = configManager.config - configUrlView.editText!!.setText( + ui.configUrlView.editText!!.setText( if (isInitialization && config.configUrl.isBlank()) CONFIG_URL_DEMO else config.configUrl ) - usernameView.editText!!.setText( + ui.usernameView.editText!!.setText( if (isInitialization && config.username.isBlank()) CONFIG_USERNAME_DEMO else config.username ) - passwordView.editText!!.setText( + ui.passwordView.editText!!.setText( if (isInitialization && config.password.isBlank()) CONFIG_PASSWORD_DEMO else config.password ) - forgetPasswordButton.visibility = if (config.hasPassword()) VISIBLE else GONE + ui.forgetPasswordButton.visibility = if (config.hasPassword()) VISIBLE else GONE } private fun checkForUrlCredentials() { - val text = configUrlView.editText!!.text.toString() + val text = ui.configUrlView.editText!!.text.toString() Uri.parse(text)?.userInfo?.let { userInfo -> if (userInfo.contains(':')) { val (user, pass) = userInfo.split(':') val strippedUrl = text.replace("${userInfo}@", "") - configUrlView.editText!!.setText(strippedUrl) - usernameView.editText!!.setText(user) - passwordView.editText!!.setText(pass) + ui.configUrlView.editText!!.setText(strippedUrl) + ui.usernameView.editText!!.setText(user) + ui.passwordView.editText!!.setText(pass) } } } @@ -157,8 +160,8 @@ class ConfigFragment : Fragment() { } private fun onResultReceived() { - progressBar.visibility = INVISIBLE - okButton.visibility = VISIBLE + ui.progressBar.visibility = INVISIBLE + ui.okButton.visibility = VISIBLE } } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt index 8cc435a..3ef48e1 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt @@ -23,18 +23,16 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_merchant_history.* import net.taler.common.exhaustive import net.taler.common.navigate import net.taler.merchantlib.OrderHistoryEntry import net.taler.merchantpos.MainViewModel -import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentMerchantHistoryBinding import net.taler.merchantpos.history.HistoryFragmentDirections.Companion.actionGlobalMerchantSettings import net.taler.merchantpos.history.HistoryFragmentDirections.Companion.actionNavHistoryToRefundFragment @@ -55,31 +53,33 @@ class HistoryFragment : Fragment(), RefundClickListener { private val historyManager by lazy { model.historyManager } private val refundManager by lazy { model.refundManager } + private lateinit var ui: FragmentMerchantHistoryBinding private val historyListAdapter = HistoryItemAdapter(this) override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_merchant_history, container, false) + ui = FragmentMerchantHistoryBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - list_history.apply { + ui.listHistory.apply { layoutManager = LinearLayoutManager(requireContext()) addItemDecoration(DividerItemDecoration(context, VERTICAL)) adapter = historyListAdapter } - swipeRefresh.setOnRefreshListener { + ui.swipeRefresh.setOnRefreshListener { Log.v(TAG, "refreshing!") historyManager.fetchHistory() } - historyManager.isLoading.observe(viewLifecycleOwner, Observer { loading -> + historyManager.isLoading.observe(viewLifecycleOwner, { loading -> Log.v(TAG, "setting refreshing to $loading") - swipeRefresh.isRefreshing = loading + ui.swipeRefresh.isRefreshing = loading }) - historyManager.items.observe(viewLifecycleOwner, Observer { result -> + historyManager.items.observe(viewLifecycleOwner, { result -> when (result) { is HistoryResult.Error -> onError(result.msg) is HistoryResult.Success -> historyListAdapter.setData(result.items) diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt index 4f8e5af..69e74ce 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt @@ -23,12 +23,10 @@ import android.view.View.INVISIBLE import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_categories.* import net.taler.merchantpos.MainViewModel -import net.taler.merchantpos.R import net.taler.merchantpos.config.Category +import net.taler.merchantpos.databinding.FragmentCategoriesBinding interface CategorySelectionListener { fun onCategorySelected(category: Category) @@ -38,6 +36,8 @@ class CategoriesFragment : Fragment(), CategorySelectionListener { private val viewModel: MainViewModel by activityViewModels() private val orderManager by lazy { viewModel.orderManager } + + private lateinit var ui: FragmentCategoriesBinding private val adapter = CategoryAdapter(this) override fun onCreateView( @@ -45,18 +45,19 @@ class CategoriesFragment : Fragment(), CategorySelectionListener { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_categories, container, false) + ui = FragmentCategoriesBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - categoriesList.apply { + ui.categoriesList.apply { adapter = this@CategoriesFragment.adapter layoutManager = LinearLayoutManager(requireContext()) } - orderManager.categories.observe(viewLifecycleOwner, Observer { categories -> + orderManager.categories.observe(viewLifecycleOwner, { categories -> adapter.setItems(categories) - progressBar.visibility = INVISIBLE + ui.progressBar.visibility = INVISIBLE }) } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt index 7291a23..1335b65 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt @@ -22,12 +22,11 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.transition.TransitionManager.beginDelayedTransition -import kotlinx.android.synthetic.main.fragment_order.* import net.taler.common.navigate import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentOrderBinding import net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionGlobalConfigFetcher import net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionOrderToMerchantSettings import net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionOrderToProcessPayment @@ -40,17 +39,20 @@ class OrderFragment : Fragment() { private val orderManager by lazy { viewModel.orderManager } private val paymentManager by lazy { viewModel.paymentManager } + private lateinit var ui: FragmentOrderBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_order, container, false) + ui = FragmentOrderBinding.inflate(inflater, container, false) + return ui.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - orderManager.currentOrderId.observe(viewLifecycleOwner, Observer { orderId -> + orderManager.currentOrderId.observe(viewLifecycleOwner, { orderId -> val liveOrder = orderManager.getOrder(orderId) onOrderSwitched(orderId, liveOrder) // add a new OrderStateFragment for each order @@ -72,39 +74,39 @@ class OrderFragment : Fragment() { private fun onOrderSwitched(orderId: Int, liveOrder: LiveOrder) { // order title - liveOrder.order.observe(viewLifecycleOwner, Observer { order -> + liveOrder.order.observe(viewLifecycleOwner, { order -> activity?.title = getString(R.string.order_label_title, order.title) }) // restart button - restartButton.setOnClickListener { liveOrder.restartOrUndo() } - liveOrder.restartState.observe(viewLifecycleOwner, Observer { state -> + ui.restartButton.setOnClickListener { liveOrder.restartOrUndo() } + liveOrder.restartState.observe(viewLifecycleOwner, { state -> beginDelayedTransition(view as ViewGroup) if (state == UNDO) { - restartButton.setText(R.string.order_undo) - restartButton.isEnabled = true - completeButton.isEnabled = false + ui.restartButton.setText(R.string.order_undo) + ui.restartButton.isEnabled = true + ui.completeButton.isEnabled = false } else { - restartButton.setText(R.string.order_restart) - restartButton.isEnabled = state == ENABLED - completeButton.isEnabled = state == ENABLED + ui.restartButton.setText(R.string.order_restart) + ui.restartButton.isEnabled = state == ENABLED + ui.completeButton.isEnabled = state == ENABLED } }) // -1 and +1 buttons - liveOrder.modifyOrderAllowed.observe(viewLifecycleOwner, Observer { allowed -> - minusButton.isEnabled = allowed - plusButton.isEnabled = allowed + liveOrder.modifyOrderAllowed.observe(viewLifecycleOwner, { allowed -> + ui.minusButton.isEnabled = allowed + ui.plusButton.isEnabled = allowed }) - minusButton.setOnClickListener { liveOrder.decreaseSelectedOrderLine() } - plusButton.setOnClickListener { liveOrder.increaseSelectedOrderLine() } + ui.minusButton.setOnClickListener { liveOrder.decreaseSelectedOrderLine() } + ui.plusButton.setOnClickListener { liveOrder.increaseSelectedOrderLine() } // previous and next button - prevButton.isEnabled = orderManager.hasPreviousOrder(orderId) - orderManager.hasNextOrder(orderId).observe(viewLifecycleOwner, Observer { hasNextOrder -> - nextButton.isEnabled = hasNextOrder + ui.prevButton.isEnabled = orderManager.hasPreviousOrder(orderId) + orderManager.hasNextOrder(orderId).observe(viewLifecycleOwner, { hasNextOrder -> + ui.nextButton.isEnabled = hasNextOrder }) - prevButton.setOnClickListener { orderManager.previousOrder() } - nextButton.setOnClickListener { orderManager.nextOrder() } + ui.prevButton.setOnClickListener { orderManager.previousOrder() } + ui.nextButton.setOnClickListener { orderManager.nextOrder() } // complete button - completeButton.setOnClickListener { + ui.completeButton.setOnClickListener { val order = liveOrder.order.value ?: return@setOnClickListener paymentManager.createPayment(order) navigate(actionOrderToProcessPayment()) diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt index b60f3a5..93c4f97 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt @@ -22,16 +22,15 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.recyclerview.selection.SelectionPredicates import androidx.recyclerview.selection.SelectionTracker import androidx.recyclerview.selection.StorageStrategy import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_order_state.* import net.taler.common.fadeIn import net.taler.common.fadeOut import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentOrderStateBinding import net.taler.merchantpos.order.OrderAdapter.OrderLineLookup class OrderStateFragment : Fragment() { @@ -39,6 +38,8 @@ class OrderStateFragment : Fragment() { private val viewModel: MainViewModel by activityViewModels() private val orderManager by lazy { viewModel.orderManager } private val liveOrder by lazy { orderManager.getOrder(orderManager.currentOrderId.value!!) } + + private lateinit var ui: FragmentOrderStateBinding private val adapter = OrderAdapter() private var tracker: SelectionTracker<String>? = null @@ -47,18 +48,19 @@ class OrderStateFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_order_state, container, false) + ui = FragmentOrderStateBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - orderList.apply { + ui.orderList.apply { adapter = this@OrderStateFragment.adapter layoutManager = LinearLayoutManager(requireContext()) } - val detailsLookup = OrderLineLookup(orderList) + val detailsLookup = OrderLineLookup(ui.orderList) val tracker = SelectionTracker.Builder( "order-selection-id", - orderList, + ui.orderList, adapter.keyProvider, detailsLookup, StorageStrategy.createStringStorage() @@ -80,16 +82,16 @@ class OrderStateFragment : Fragment() { liveOrder.selectOrderLine(item) } }) - liveOrder.order.observe(viewLifecycleOwner, Observer { order -> + liveOrder.order.observe(viewLifecycleOwner, { order -> onOrderChanged(order, tracker) }) - liveOrder.orderTotal.observe(viewLifecycleOwner, Observer { orderTotal -> + liveOrder.orderTotal.observe(viewLifecycleOwner, { orderTotal -> if (orderTotal.isZero()) { - totalView.fadeOut() - totalView.text = null + ui.totalView.fadeOut() + ui.totalView.text = null } else { - totalView.text = getString(R.string.order_total, orderTotal) - totalView.fadeIn() + ui.totalView.text = getString(R.string.order_total, orderTotal) + ui.totalView.fadeIn() } }) } @@ -104,9 +106,8 @@ class OrderStateFragment : Fragment() { liveOrder.lastAddedProduct?.let { val position = adapter.findPosition(it) if (position >= 0) { - // orderList can be null m( - orderList?.scrollToPosition(position) - orderList?.post { this.tracker?.select(it.id) } + ui.orderList.scrollToPosition(position) + ui.orderList.post { this.tracker?.select(it.id) } } } // workaround for bug: SelectionObserver doesn't update when removing selected item diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt index 00eb509..a3898fd 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt @@ -24,14 +24,13 @@ import android.view.ViewGroup import android.widget.TextView import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView.Adapter import androidx.recyclerview.widget.RecyclerView.ViewHolder -import kotlinx.android.synthetic.main.fragment_products.* import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R import net.taler.merchantpos.config.ConfigProduct +import net.taler.merchantpos.databinding.FragmentProductsBinding import net.taler.merchantpos.order.ProductAdapter.ProductViewHolder interface ProductSelectionListener { @@ -44,27 +43,30 @@ class ProductsFragment : Fragment(), ProductSelectionListener { private val orderManager by lazy { viewModel.orderManager } private val adapter = ProductAdapter(this) + private lateinit var ui: FragmentProductsBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_products, container, false) + ui = FragmentProductsBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - productsList.apply { + ui.productsList.apply { adapter = this@ProductsFragment.adapter layoutManager = GridLayoutManager(requireContext(), 3) } - orderManager.products.observe(viewLifecycleOwner, Observer { products -> + orderManager.products.observe(viewLifecycleOwner, { products -> if (products == null) { adapter.setItems(emptyList()) } else { adapter.setItems(products) } - progressBar.visibility = INVISIBLE + ui.progressBar.visibility = INVISIBLE }) } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt index 10d538d..5b95dea 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt @@ -22,21 +22,23 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController -import kotlinx.android.synthetic.main.fragment_payment_success.* -import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentPaymentSuccessBinding class PaymentSuccessFragment : Fragment() { + private lateinit var ui: FragmentPaymentSuccessBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_payment_success, container, false) + ui = FragmentPaymentSuccessBinding.inflate(inflater, container, false) + return ui.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - paymentButton.setOnClickListener { + ui.paymentButton.setOnClickListener { findNavController().navigateUp() } } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt index 27ef366..5c0a894 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt @@ -22,10 +22,8 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG -import kotlinx.android.synthetic.main.fragment_process_payment.* import net.taler.common.NfcManager.Companion.hasNfc import net.taler.common.QrCodeManager.makeQrCode import net.taler.common.fadeIn @@ -33,6 +31,7 @@ import net.taler.common.fadeOut import net.taler.common.navigate import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentProcessPaymentBinding import net.taler.merchantpos.payment.ProcessPaymentFragmentDirections.Companion.actionProcessPaymentToPaymentSuccess import net.taler.merchantpos.topSnackbar @@ -41,21 +40,24 @@ class ProcessPaymentFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val paymentManager by lazy { model.paymentManager } + private lateinit var ui: FragmentProcessPaymentBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_process_payment, container, false) + ui = FragmentProcessPaymentBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val introRes = if (hasNfc(requireContext())) R.string.payment_intro_nfc else R.string.payment_intro - payIntroView.setText(introRes) - paymentManager.payment.observe(viewLifecycleOwner, Observer { payment -> + ui.payIntroView.setText(introRes) + paymentManager.payment.observe(viewLifecycleOwner, { payment -> onPaymentStateChanged(payment) }) - cancelPaymentButton.setOnClickListener { + ui.cancelPaymentButton.setOnClickListener { onPaymentCancel() } } @@ -76,17 +78,17 @@ class ProcessPaymentFragment : Fragment() { navigate(actionProcessPaymentToPaymentSuccess()) return } - payIntroView.fadeIn() - amountView.text = payment.order.total.toString() + ui.payIntroView.fadeIn() + ui.amountView.text = payment.order.total.toString() payment.orderId?.let { - orderRefView.text = getString(R.string.payment_order_id, it) - orderRefView.fadeIn() + ui.orderRefView.text = getString(R.string.payment_order_id, it) + ui.orderRefView.fadeIn() } payment.talerPayUri?.let { val qrcodeBitmap = makeQrCode(it) - qrcodeView.setImageBitmap(qrcodeBitmap) - qrcodeView.fadeIn() - progressBar.fadeOut() + ui.qrcodeView.setImageBitmap(qrcodeBitmap) + ui.qrcodeView.fadeIn() + ui.progressBar.fadeOut() } } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt index 752b7aa..91e68e6 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt @@ -22,11 +22,9 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.fragment_refund.* import net.taler.common.fadeIn import net.taler.common.fadeOut import net.taler.common.navigate @@ -35,6 +33,7 @@ import net.taler.lib.common.AmountParserException import net.taler.merchantlib.OrderHistoryEntry import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentRefundBinding import net.taler.merchantpos.refund.RefundFragmentDirections.Companion.actionRefundFragmentToRefundUriFragment import net.taler.merchantpos.refund.RefundResult.AlreadyRefunded import net.taler.merchantpos.refund.RefundResult.Error @@ -46,44 +45,47 @@ class RefundFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val refundManager by lazy { model.refundManager } + private lateinit var ui: FragmentRefundBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_refund, container, false) + ui = FragmentRefundBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val item = refundManager.toBeRefunded ?: throw IllegalStateException() - amountInputView.setText(item.amount.amountStr) - currencyView.text = item.amount.currency - abortButton.setOnClickListener { findNavController().navigateUp() } - refundButton.setOnClickListener { onRefundButtonClicked(item) } + ui.amountInputView.setText(item.amount.amountStr) + ui.currencyView.text = item.amount.currency + ui.abortButton.setOnClickListener { findNavController().navigateUp() } + ui.refundButton.setOnClickListener { onRefundButtonClicked(item) } - refundManager.refundResult.observe(viewLifecycleOwner, Observer { result -> + refundManager.refundResult.observe(viewLifecycleOwner, { result -> onRefundResultChanged(result) }) } private fun onRefundButtonClicked(item: OrderHistoryEntry) { val inputAmount = try { - Amount.fromString(item.amount.currency, amountInputView.text.toString()) + Amount.fromString(item.amount.currency, ui.amountInputView.text.toString()) } catch (e: AmountParserException) { - amountView.error = getString(R.string.refund_error_invalid_amount) + ui.amountView.error = getString(R.string.refund_error_invalid_amount) return } if (inputAmount > item.amount) { - amountView.error = getString(R.string.refund_error_max_amount, item.amount.amountStr) + ui.amountView.error = getString(R.string.refund_error_max_amount, item.amount.amountStr) return } if (inputAmount.isZero()) { - amountView.error = getString(R.string.refund_error_zero) + ui.amountView.error = getString(R.string.refund_error_zero) return } - amountView.error = null - refundButton.fadeOut() - progressBar.fadeIn() - refundManager.refund(item, inputAmount, reasonInputView.text.toString()) + ui.amountView.error = null + ui.refundButton.fadeOut() + ui.progressBar.fadeIn() + refundManager.refund(item, inputAmount, ui.reasonInputView.text.toString()) } private fun onRefundResultChanged(result: RefundResult?): Any = when (result) { @@ -91,8 +93,8 @@ class RefundFragment : Fragment() { PastDeadline -> onError(getString(R.string.refund_error_deadline)) AlreadyRefunded -> onError(getString(R.string.refund_error_already_refunded)) is Success -> { - progressBar.fadeOut() - refundButton.fadeIn() + ui.progressBar.fadeOut() + ui.refundButton.fadeIn() navigate(actionRefundFragmentToRefundUriFragment()) } null -> { // no-op @@ -101,8 +103,8 @@ class RefundFragment : Fragment() { private fun onError(msg: String) { Snackbar.make(requireView(), msg, LENGTH_LONG).show() - progressBar.fadeOut() - refundButton.fadeIn() + ui.progressBar.fadeOut() + ui.refundButton.fadeIn() } } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt index b8e8997..5e52404 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt @@ -23,22 +23,25 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController -import kotlinx.android.synthetic.main.fragment_refund_uri.* import net.taler.common.NfcManager.Companion.hasNfc import net.taler.common.QrCodeManager.makeQrCode import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R +import net.taler.merchantpos.databinding.FragmentRefundUriBinding class RefundUriFragment : Fragment() { private val model: MainViewModel by activityViewModels() private val refundManager by lazy { model.refundManager } + private lateinit var ui: FragmentRefundUriBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_refund_uri, container, false) + ui = FragmentRefundUriBinding.inflate(inflater, container, false) + return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -46,19 +49,19 @@ class RefundUriFragment : Fragment() { val result = refundManager.refundResult.value if (result !is RefundResult.Success) throw IllegalStateException() - refundQrcodeView.setImageBitmap(makeQrCode(result.refundUri)) + ui.refundQrcodeView.setImageBitmap(makeQrCode(result.refundUri)) val introRes = if (hasNfc(requireContext())) R.string.refund_intro_nfc else R.string.refund_intro - refundIntroView.setText(introRes) + ui.refundIntroView.setText(introRes) - refundAmountView.text = result.amount.toString() + ui.refundAmountView.text = result.amount.toString() - refundRefView.text = + ui.refundRefView.text = getString(R.string.refund_order_ref, result.item.orderId, result.reason) - cancelRefundButton.setOnClickListener { findNavController().navigateUp() } - completeButton.setOnClickListener { findNavController().navigateUp() } + ui.cancelRefundButton.setOnClickListener { findNavController().navigateUp() } + ui.completeButton.setOnClickListener { findNavController().navigateUp() } } override fun onDestroy() { diff --git a/merchant-terminal/src/main/res/layout/activity_main.xml b/merchant-terminal/src/main/res/layout/activity_main.xml index 1285b19..c801563 100644 --- a/merchant-terminal/src/main/res/layout/activity_main.xml +++ b/merchant-terminal/src/main/res/layout/activity_main.xml @@ -24,6 +24,7 @@ tools:openDrawer="start"> <include + android:id="@+id/main" layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> |