]> git.ktnx.net Git - mobile-ledger-staging.git/commitdiff
New transaction: locale aware number input
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Wed, 13 Nov 2019 21:38:58 +0000 (23:38 +0200)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Wed, 13 Nov 2019 21:38:58 +0000 (23:38 +0200)
uses hacks on pre-O devices that break inserting "-" at the beginning
(requires that the minus is entered on an empty field)

app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionItemHolder.java

index 123b91e93ae534e24103b2a3e3a572f729006812..c455a01434cdc186d281dfc6df29d4acf2cc07be 100644 (file)
 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;
@@ -42,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;
@@ -49,6 +52,8 @@ 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;
@@ -96,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) {
@@ -119,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)
@@ -257,6 +302,7 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder
 
                     if (!amount.isEmpty()) {
                         try {
+                            amount = amount.replace(decimalSeparator, decimalDot);
                             item.getAccount()
                                 .setAmount(Float.parseFloat(amount));
                         }