From 1055c19ff58972642be04ac3ec01fd3836e60608 Mon Sep 17 00:00:00 2001 From: AlinaStepanova Date: Mon, 6 Apr 2020 18:21:01 +0300 Subject: [PATCH] add comments --- .../com/avs/rates/currency/BaseCurrency.kt | 3 ++ .../java/com/avs/rates/ui/BaseActivity.kt | 2 +- .../avs/rates/ui/main/CurrenciesAdapter.kt | 40 ++++++++++++++++++- .../com/avs/rates/ui/main/MainActivity.kt | 21 +++++++--- .../com/avs/rates/ui/main/MainViewModel.kt | 1 + .../main/java/com/avs/rates/utils/Format.kt | 10 +++++ app/src/main/res/layout/rate_item_list.xml | 2 +- app/src/main/res/values/dimens.xml | 1 + .../java/com/avs/rates/utils/FormatKtTest.kt | 11 +++++ 9 files changed, 83 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/avs/rates/currency/BaseCurrency.kt b/app/src/main/java/com/avs/rates/currency/BaseCurrency.kt index db5100f..df2f042 100644 --- a/app/src/main/java/com/avs/rates/currency/BaseCurrency.kt +++ b/app/src/main/java/com/avs/rates/currency/BaseCurrency.kt @@ -3,6 +3,9 @@ package com.avs.rates.currency import com.avs.rates.DEFAULT_RATE_VALUE import com.avs.rates.R +/** + * Base class for every currency. Holds common data and methods. + */ abstract class BaseCurrency { var rate: Double = DEFAULT_RATE_VALUE diff --git a/app/src/main/java/com/avs/rates/ui/BaseActivity.kt b/app/src/main/java/com/avs/rates/ui/BaseActivity.kt index 1b1b087..f5a4d1f 100644 --- a/app/src/main/java/com/avs/rates/ui/BaseActivity.kt +++ b/app/src/main/java/com/avs/rates/ui/BaseActivity.kt @@ -7,7 +7,7 @@ import com.avs.rates.di.ViewModelFactory /** * A class which serve as a parent to all activities classes in the app. - * Contains common data and methods + * Contains common data and methods. */ abstract class BaseActivity : AppCompatActivity() { diff --git a/app/src/main/java/com/avs/rates/ui/main/CurrenciesAdapter.kt b/app/src/main/java/com/avs/rates/ui/main/CurrenciesAdapter.kt index ab372a2..359167b 100644 --- a/app/src/main/java/com/avs/rates/ui/main/CurrenciesAdapter.kt +++ b/app/src/main/java/com/avs/rates/ui/main/CurrenciesAdapter.kt @@ -7,16 +7,18 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.avs.rates.R import com.avs.rates.currency.BaseCurrency import com.avs.rates.databinding.RateItemListBinding import com.avs.rates.utils.CircleTransform import com.avs.rates.utils.formatNumber +import com.avs.rates.utils.getSelectionIndex import com.squareup.picasso.Picasso import java.util.* interface RatesListener { fun onListItemClick(newBaseCurrency: BaseCurrency) - fun onEditTextChanged(text: String) + fun onEditTextChanged(stringValue: String) } class CurrenciesAdapter( @@ -29,6 +31,10 @@ class CurrenciesAdapter( private var textWatcher = getTextWatcher() private var currencies: LinkedList? = currencyList + /** + * Updates currencies list + * @param currencies - updated list of currencies + */ fun setCurrencies(currencies: LinkedList?) { this.currencies = currencies notifyItemRangeChanged(1, (this.currencies?.size?.minus(1) ?: 0)) @@ -50,6 +56,9 @@ class CurrenciesAdapter( } } + /** + * Update first two top items after base currency has changed + */ fun updateTopItems() { if (itemCount != 0) notifyItemChanged(0) if (itemCount > 0) notifyItemChanged(1) @@ -58,9 +67,12 @@ class CurrenciesAdapter( inner class RatesViewHolder(private val binding: RateItemListBinding) : RecyclerView.ViewHolder(binding.root), View.OnClickListener { + private val editTextMaxLength : Int + init { binding.root.setOnClickListener(this) binding.editText.setOnClickListener(this) + editTextMaxLength = context.resources.getInteger(R.integer.edit_text_max_length) } fun bind(item: BaseCurrency, context: Context) { @@ -70,14 +82,27 @@ class CurrenciesAdapter( bindFlagImage(item.getImagePath()) } + /** + * Sets short currency name to a corresponding text view + * @param name - short name of currency + */ private fun bindCurrencyShortName(name: String?) { if (name != null) binding.tvCurrencyShortName.text = name } + /** + * Sets full currency name to a corresponding text view + * @param name - full name of currency + */ private fun bindCurrencyFullName(name: String?) { if (name != null) binding.tvCurrencyFullName.text = name } + /** + * Disables all the edit texts in the recycler view except for the top one. + * Sets rate value. + * @param value - a rate value + */ private fun bindRate(value: String) { binding.editText.removeTextChangedListener(textWatcher) binding.editText.isEnabled = adapterPosition == 0 @@ -86,9 +111,14 @@ class CurrenciesAdapter( binding.editText.addTextChangedListener(textWatcher) itemClickListener.onEditTextChanged(binding.editText.text.toString()) binding.editText.requestFocus() + binding.editText.setSelection(getSelectionIndex(value.length, editTextMaxLength)) } } + /** + * Loads image url into a image view using custom circle transformation + * @param imageUrl - country flag url + */ private fun bindFlagImage(imageUrl: String?) { Picasso.get() .load(imageUrl) @@ -97,6 +127,10 @@ class CurrenciesAdapter( .into(binding.ivFlagImage) } + /** + * Changes base currency to appear on the top, if not a first item was clicked + * @param view - recycler view item + */ override fun onClick(view: View?) { val clickedPosition = adapterPosition if (clickedPosition != 0 && !currencies.isNullOrEmpty()) { @@ -112,6 +146,10 @@ class CurrenciesAdapter( } } + /** + * Listens to a rate changing of a base currency + * @return + */ private fun getTextWatcher(): TextWatcher { return object : TextWatcher { diff --git a/app/src/main/java/com/avs/rates/ui/main/MainActivity.kt b/app/src/main/java/com/avs/rates/ui/main/MainActivity.kt index c63b4d3..3466e29 100644 --- a/app/src/main/java/com/avs/rates/ui/main/MainActivity.kt +++ b/app/src/main/java/com/avs/rates/ui/main/MainActivity.kt @@ -15,7 +15,6 @@ import com.avs.rates.ui.BaseActivity import java.util.* import javax.inject.Inject - class MainActivity : BaseActivity(), RatesListener { @Inject @@ -55,18 +54,30 @@ class MainActivity : BaseActivity(), RatesListener { }) } + /** + * Triggered when used has selected new base currency + * @param newBaseCurrency - new base currency + */ override fun onListItemClick(newBaseCurrency: BaseCurrency) { binding.recyclerView.itemAnimator = defaultItemAnimator viewModel.handleUserInteraction(newBaseCurrency) binding.recyclerView.layoutManager?.scrollToPosition(0) } - override fun onEditTextChanged(text: String) { - viewModel.updateBaseCurrencyValue(text) + /** + * Triggered when used has changed a rate of a base currency + * @param stringValue - updated rate value of a base currency + */ + override fun onEditTextChanged(stringValue: String) { + viewModel.updateBaseCurrencyValue(stringValue) } - private fun handleErrorItemsAppearance(it: ErrorType?) { - when (it) { + /** + * Manages UI items visibility in a case when network error has occurred before recycler view was shown + * @param errorType - network related type of error + */ + private fun handleErrorItemsAppearance(errorType: ErrorType?) { + when (errorType) { null -> { binding.ivCloud.visibility = View.INVISIBLE binding.ivMessage.visibility = View.INVISIBLE diff --git a/app/src/main/java/com/avs/rates/ui/main/MainViewModel.kt b/app/src/main/java/com/avs/rates/ui/main/MainViewModel.kt index 7e3b6bd..d656363 100644 --- a/app/src/main/java/com/avs/rates/ui/main/MainViewModel.kt +++ b/app/src/main/java/com/avs/rates/ui/main/MainViewModel.kt @@ -168,6 +168,7 @@ class MainViewModel @Inject constructor( */ fun updateBaseCurrencyValue(text: String) { baseCurrencyValue = text.toDoubleOrNull() ?: -1.0 + currenciesList.first.rate = baseCurrencyValue } /** diff --git a/app/src/main/java/com/avs/rates/utils/Format.kt b/app/src/main/java/com/avs/rates/utils/Format.kt index 14b57ac..87bf7ae 100644 --- a/app/src/main/java/com/avs/rates/utils/Format.kt +++ b/app/src/main/java/com/avs/rates/utils/Format.kt @@ -34,4 +34,14 @@ fun round(value: Double, decimalPlace: Int): Double { var number = BigDecimal(value.toString()) number = number.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP) return number.toDouble() +} + +/** + * + * @param rateValueLength - rate value length + * @param maxLength - max allowed length of tne elements to be inserted in an edit text + * @return cursor position + */ +fun getSelectionIndex(rateValueLength: Int, maxLength: Int) : Int { + return if (rateValueLength > maxLength) maxLength else rateValueLength } \ No newline at end of file diff --git a/app/src/main/res/layout/rate_item_list.xml b/app/src/main/res/layout/rate_item_list.xml index d16e06f..21a1159 100644 --- a/app/src/main/res/layout/rate_item_list.xml +++ b/app/src/main/res/layout/rate_item_list.xml @@ -67,7 +67,7 @@ android:hint="@string/edit_text_hint" android:inputType="numberDecimal" android:maxEms="7" - android:maxLength="12" + android:maxLength="@integer/edit_text_max_length" android:minEms="2" android:textAlignment="textEnd" android:textColor="@color/colorBlack" diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 71d4b38..ed5b66c 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -8,4 +8,5 @@ 16dp 32dp 56dp + 18 \ No newline at end of file diff --git a/app/src/test/java/com/avs/rates/utils/FormatKtTest.kt b/app/src/test/java/com/avs/rates/utils/FormatKtTest.kt index 1a168ad..159220f 100644 --- a/app/src/test/java/com/avs/rates/utils/FormatKtTest.kt +++ b/app/src/test/java/com/avs/rates/utils/FormatKtTest.kt @@ -36,4 +36,15 @@ class FormatKtTest { assertEquals(round(value, 2), 1234.01, delta) assertEquals(round(value, 3), 1234.01, delta) } + + @Test + fun getSelectionIndexTest() { + var valueLength = 10 + val maxLength = 18 + assertEquals(getSelectionIndex(valueLength, maxLength), valueLength) + valueLength = 22 + assertEquals(getSelectionIndex(valueLength, maxLength), maxLength) + valueLength = 18 + assertEquals(getSelectionIndex(valueLength, maxLength), valueLength) + } } \ No newline at end of file