X-Git-Url: https://git.ktnx.net/?p=mobile-ledger.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2Factivity%2FNewTransactionItemHolder.java;h=57bdbfdcdf2c1f1887adbf47bc2feaea729cdcd1;hp=a5a4541fd3579635fe102e53dc55f1a14f327ad7;hb=96b5e3772e7f0c13750c378ea788455d0f26cca6;hpb=048d949ea24d8971bd2c29ae9613e0e4373d2e37 diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionItemHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionItemHolder.java index a5a4541f..57bdbfdc 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionItemHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionItemHolder.java @@ -17,8 +17,11 @@ package net.ktnx.mobileledger.ui.activity; +import android.annotation.SuppressLint; +import android.os.Build; import android.text.Editable; import android.text.TextWatcher; +import android.text.method.DigitsKeyListener; import android.view.View; import android.view.inputmethod.EditorInfo; import android.widget.AutoCompleteTextView; @@ -27,7 +30,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.appcompat.widget.LinearLayoutCompat; import androidx.lifecycle.Observer; import androidx.recyclerview.widget.RecyclerView; @@ -41,6 +44,7 @@ import net.ktnx.mobileledger.utils.Logger; import net.ktnx.mobileledger.utils.MLDB; import net.ktnx.mobileledger.utils.Misc; +import java.text.DecimalFormatSymbols; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -48,12 +52,14 @@ import java.util.Locale; class NewTransactionItemHolder extends RecyclerView.ViewHolder implements DatePickerFragment.DatePickedListener, DescriptionSelectedCallback { + private final String decimalSeparator; + private final String decimalDot; private NewTransactionModel.Item item; private TextView tvDate; private AutoCompleteTextView tvDescription; private AutoCompleteTextView tvAccount; private TextView tvAmount; - private ConstraintLayout lHead; + private LinearLayoutCompat lHead; private LinearLayout lAccount; private FrameLayout lPadding; private MobileLedgerProfile mProfile; @@ -95,6 +101,11 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder MLDB.hookAutocompletionAdapter(tvAccount.getContext(), tvAccount, MLDB.ACCOUNTS_TABLE, "name", true, this, mProfile); + // FIXME: react on configuration (locale) changes + decimalSeparator = String.valueOf(DecimalFormatSymbols.getInstance() + .getMonetaryDecimalSeparator()); + decimalDot = "."; + final TextWatcher tw = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -118,9 +129,44 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder Logger.debug("textWatcher", "done"); } }; + final TextWatcher amountWatcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + @Override + public void afterTextChanged(Editable s) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + // only one decimal separator is allowed + // plus and minus are allowed only at the beginning + String val = s.toString(); + if (val.isEmpty()) + tvAmount.setKeyListener(DigitsKeyListener.getInstance( + "0123456789+-" + decimalSeparator + decimalDot)); + else if (val.contains(decimalSeparator) || val.contains(decimalDot)) + tvAmount.setKeyListener(DigitsKeyListener.getInstance("0123456789")); + else + tvAmount.setKeyListener(DigitsKeyListener.getInstance( + "0123456789" + decimalSeparator + decimalDot)); + + syncData(); + adapter.model.checkTransactionSubmittable(adapter); + } + } + }; tvDescription.addTextChangedListener(tw); tvAccount.addTextChangedListener(tw); - tvAmount.addTextChangedListener(tw); + tvAmount.addTextChangedListener(amountWatcher); + + // FIXME: react on locale changes + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + tvAmount.setKeyListener(DigitsKeyListener.getInstance(Locale.getDefault(), true, true)); + else + tvAmount.setKeyListener( + DigitsKeyListener.getInstance("0123456789+-" + decimalSeparator + decimalDot)); dateObserver = date -> { if (syncingData) @@ -149,7 +195,10 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder return; syncingData = true; try { - tvAmount.setHint(hint); + if (hint == null) + tvAmount.setHint(R.string.zero_amount); + else + tvAmount.setHint(hint); } finally { syncingData = false; @@ -251,23 +300,24 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder String amount = String.valueOf(tvAmount.getText()); amount = amount.trim(); - if (!amount.isEmpty()) { + if (amount.isEmpty()) { + item.getAccount() + .resetAmount(); + } + else { try { + amount = amount.replace(decimalSeparator, decimalDot); item.getAccount() .setAmount(Float.parseFloat(amount)); } catch (NumberFormatException e) { Logger.debug("new-trans", String.format( "assuming amount is not set due to number format exception. " + - "input was '%s'", - amount)); + "input was '%s'", amount)); item.getAccount() .resetAmount(); } } - else - item.getAccount() - .resetAmount(); break; case bottomFiller: @@ -289,6 +339,7 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder * * @param item updates the UI elements with the data from the model item */ + @SuppressLint("DefaultLocale") public void setData(NewTransactionModel.Item item) { beginUpdates(); try { @@ -317,9 +368,14 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder case transactionRow: LedgerTransactionAccount acc = item.getAccount(); tvAccount.setText(acc.getAccountName()); - tvAmount.setText( - acc.isAmountSet() ? String.format(Locale.US, "%1.2f", acc.getAmount()) - : ""); + if (acc.isAmountSet()) { + tvAmount.setText(String.format("%1.2f", acc.getAmount())); + } + else { + tvAmount.setText(""); +// tvAmount.setHint(R.string.zero_amount); + } + tvAmount.setHint(item.getAmountHint()); lHead.setVisibility(View.GONE); lAccount.setVisibility(View.VISIBLE); lPadding.setVisibility(View.GONE);