মুদ্রার ইনপুট সম্পাদনা পাঠ্য বিন্যাসের আরও ভাল উপায়?


91

আমার একটি এডিটেক্সট রয়েছে, শুরুর মান $ 0.00। আপনি 1 টি চাপলে এটি 0.01 ডলারে পরিবর্তিত হয়। 4 টিপুন, এটি $ 0.14 এ যায়। 8, $ 1.48 টিপুন। ব্যাকস্পেস, $ 0.14 ইত্যাদি চাপুন

এটি কাজ করে, সমস্যাটি হ'ল কেউ যদি ম্যানুয়ালি কার্সারটি অবস্থান করে তবে ফরম্যাটিংয়ে সমস্যা দেখা দেয়। যদি তারা দশমিক মুছতে থাকে তবে এটি আর ফিরে আসবে না। যদি তারা দশমিকের সামনে কার্সারটি রেখে দেয় এবং টাইপ 2 করে, এটি $ 2.00 এর পরিবর্তে .00 02.00 প্রদর্শন করবে। যদি তারা মুছে ফেলার চেষ্টা করে $ এটি পরিবর্তে একটি অঙ্ক মুছবে, উদাহরণস্বরূপ।

এখানে আমি ব্যবহার করছি কোড, আমি কোন পরামর্শ প্রশংসা করব।

mEditPrice.setRawInputType(Configuration.KEYBOARD_12KEY);
    public void priceClick(View view) {
    mEditPrice.addTextChangedListener(new TextWatcher(){
        DecimalFormat dec = new DecimalFormat("0.00");
        @Override
        public void afterTextChanged(Editable arg0) {
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start,
                int count, int after) {
        }
        @Override
        public void onTextChanged(CharSequence s, int start,
                int before, int count) {
            if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
            {
                String userInput= ""+s.toString().replaceAll("[^\\d]", "");
                if (userInput.length() > 0) {
                    Float in=Float.parseFloat(userInput);
                    float percen = in/100;
                    mEditPrice.setText("$"+dec.format(percen));
                    mEditPrice.setSelection(mEditPrice.getText().length());
                }
            }
        }
    });

4
আমার অজ্ঞতা ক্ষমা করুন, তবে এই কোডটি কী ক্রিয়াকলাপের জীবনচক্র পদ্ধতির কোনও একটি থেকে স্নিপেট, বা সেগুলি আপনি তৈরি কাস্টম শ্রেণিতে আছেন? আপনি দয়া করে আরও একটি সম্পূর্ণ কোড নমুনা সরবরাহ করতে পারেন? ধন্যবাদ!
আরগাস

এটি আমার জন্য কাজ করে আমি এই বাহ্যিক
লিবটি

উত্তর:


153

আমি আপনার পদ্ধতিটি পরীক্ষা করেছি, তবে যখন আমি প্রচুর সংখ্যা ব্যবহার করি তখন এটি ব্যর্থ হয় ... আমি এটি তৈরি করেছি:

private String current = "";
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if(!s.toString().equals(current)){
       [your_edittext].removeTextChangedListener(this);

       String cleanString = s.toString().replaceAll("[$,.]", "");
                
       double parsed = Double.parseDouble(cleanString);
       String formatted = NumberFormat.getCurrencyInstance().format((parsed/100));
                    
       current = formatted;
       [your_edittext].setText(formatted);
       [your_edittext].setSelection(formatted.length());
       
       [your_edittext].addTextChangedListener(this);
    }
}

কোটলিন বৈকল্পিক:

private var current: String = ""

         override fun onTextChanged(
            s: CharSequence,
            start: Int,
            before: Int,
            count: Int
        ) {
            if (s.toString() != current) {
                discount_amount_edit_text.removeTextChangedListener(this)

                val cleanString: String = s.replace("""[$,.]""".toRegex(), "")

                val parsed = cleanString.toDouble()
                val formatted = NumberFormat.getCurrencyInstance().format((parsed / 100))

                current = formatted
                discount_amount_edit_text.setText(formatted)
                discount_amount_edit_text.setSelection(formatted.length)

                discount_amount_edit_text.addTextChangedListener(this)
            }
        }

36
ডলার প্রতীক ধরে String replaceable = String.format("[%s,.]", NumberFormat.getCurrencyInstance().getCurrency().getSymbol()); String cleanString = s.toString().replaceAll(replaceable, "");
নেওয়ার

6
হুম, আসলে এখন এটি চেষ্টা করেছি, প্রতিস্থাপনের সমস্ত থেকে রেইগেক্স প্যাটার্নটি এমনভাবে দেখা উচিত, স্পেসগুলিও পরিচালনা করতে হবে: String replaceable = String.format("[%s,.\\s]", NumberFormat.getCurrencyInstance().getCurrency().getSymbol());
ক্রেগ

6
টেক্সট চেঞ্জড () `onTextChanged() and rather to do so in
কোডডুঞ্জার

4
আমি জানতে আগ্রহী কেন পাঠ্য পরিবর্তিত শ্রোতা কেন সরানো হয় এবং তারপরে প্রতিবার পুনরায় যুক্ত করা হয়? আমার জন্য এটি কেবল একবার যুক্ত হলে কাজ করে (এবং আমি পরিবর্তনগুলি পরবর্তী পাঠ্যক্রমটিতে সরিয়ে নিয়েছি)
ড্যানিয়েল উইলসন

4
আপনি 1 -> 0 -> 0 রাখলে আমি কাজ করি না 1,00 পেতে। তার কারণ আপনার বিন্দু যা 0,1 ২010 স্ট্রিং মধ্যে পরিবর্তিত হয় এবং ২010 মধ্যে পেতে double10. হয় 10 / 100 = 0,1আপনি এটা অতীত পেতে পারে না।
JakubW

30

উপরের কয়েকটি উত্তরের উপর ভিত্তি করে আমি একটি MoneyTextWatcher তৈরি করেছি যা আপনি নীচে ব্যবহার করবেন:

priceEditText.addTextChangedListener(new MoneyTextWatcher(priceEditText));

এবং এখানে ক্লাস:

public class MoneyTextWatcher implements TextWatcher {
    private final WeakReference<EditText> editTextWeakReference;

    public MoneyTextWatcher(EditText editText) {
        editTextWeakReference = new WeakReference<EditText>(editText);
    }

    @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 editable) {
        EditText editText = editTextWeakReference.get();
        if (editText == null) return;
        String s = editable.toString();
        if (s.isEmpty()) return;
        editText.removeTextChangedListener(this);
        String cleanString = s.replaceAll("[$,.]", "");
        BigDecimal parsed = new BigDecimal(cleanString).setScale(2, BigDecimal.ROUND_FLOOR).divide(new BigDecimal(100), BigDecimal.ROUND_FLOOR);
        String formatted = NumberFormat.getCurrencyInstance().format(parsed);
        editText.setText(formatted);
        editText.setSelection(formatted.length());
        editText.addTextChangedListener(this);
    }
}

আমি এটি কিছুক্ষণের জন্য ব্যবহার করছি তবে সম্প্রতি একটি ছোট সমস্যা পেয়েছি, যদি আপনি কিছু কীবোর্ডগুলিতে মুছুন বোতামটি ধরে রাখেন তবে এটি পুরো শব্দ / গোষ্ঠীর পাঠ্য এবং কারণগুলি মুছে java.lang.NumberFormatException: Bad offset/length
ফেলবে

4
এটা আমার জন্য পুরোপুরি কাজ করেন! 'EditText.setSelection (formatted.length ()) এ মনোযোগ দিন;' এডিট টেক্সট প্রশ্নে প্রশ্নে অবশ্যই 'সর্বাধিক দৈর্ঘ্যের' সম্পত্তিতে লক্ষ্য করা উচিত। সর্বোচ্চ দৈর্ঘ্য == 13; formatted.length () == 14; যদি 'ফর্ম্যাটড.লেথেনথ' 'ম্যাক্সেলেন্থ'-এর চেয়ে বেশি হয় তবে নিম্নলিখিত ত্রুটি ঘটে: সূচিপত্র-অফফাউন্ডস এক্সেক্সশন: সেটস্প্যান (14 ... 14) দৈর্ঘ্য 13
টাকেরও

4
ব্লুজেেনি এটি ঠিক করতে ঠিক করুন যে (s.isEmpty ()) ফিরে আসে তবে পাঠ্য পরিবর্তন শ্রোতাদের অপসারণ করার আগে একটি s.isEmpty চেক যুক্ত করুন; editText.removeTextChangedListener (এটি); ক্লিনস্ট্রিং লাইনেও s.toString () অপ্রয়োজনীয়
মাইক বাগলিও জুনিয়র

4
কেবলমাত্র একটি পরামর্শের চেয়ে সেরা উত্তর হ'ল -> .repreAll ("[^ \\ d।]", "") এর জন্য .replaceAll ("[$ ...) পরিবর্তন করা; যেহেতু আপনি অন্যান্য মুদ্রার সাথে অন্য অক্ষরও কেবলমাত্র $, আমার ক্ষেত্রে যেমন ছিল $ (ব্রাজিলিয়ান)
ব্যবহারকারী 2582318

4
দুঃখিত, সঠিক পরামর্শটি হ'ল এটি -> .replaceAll("[^0-9]", ""), উপরেরটির সীমা রয়েছে 9.999.999 -_-
ব্যবহারকারী 2582318

21

এখানে আমার রীতি আছে CurrencyEditText

import android.content.Context;import android.graphics.Rect;import android.text.Editable;import android.text.InputFilter;import android.text.InputType;import android.text.TextWatcher;
import android.util.AttributeSet;import android.widget.EditText;import java.math.BigDecimal;import java.math.RoundingMode;
import java.text.DecimalFormat;import java.text.DecimalFormatSymbols;
import java.util.Locale;

/**
 * Some note <br/>
 * <li>Always use locale US instead of default to make DecimalFormat work well in all language</li>
 */
public class CurrencyEditText extends android.support.v7.widget.AppCompatEditText {
    private static String prefix = "VND ";
    private static final int MAX_LENGTH = 20;
    private static final int MAX_DECIMAL = 3;
    private CurrencyTextWatcher currencyTextWatcher = new CurrencyTextWatcher(this, prefix);

    public CurrencyEditText(Context context) {
        this(context, null);
    }

    public CurrencyEditText(Context context, AttributeSet attrs) {
        this(context, attrs, android.support.v7.appcompat.R.attr.editTextStyle);
    }

    public CurrencyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
        this.setHint(prefix);
        this.setFilters(new InputFilter[] { new InputFilter.LengthFilter(MAX_LENGTH) });
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused) {
            this.addTextChangedListener(currencyTextWatcher);
        } else {
            this.removeTextChangedListener(currencyTextWatcher);
        }
        handleCaseCurrencyEmpty(focused);
    }

    /**
     * When currency empty <br/>
     * + When focus EditText, set the default text = prefix (ex: VND) <br/>
     * + When EditText lose focus, set the default text = "", EditText will display hint (ex:VND)
     */
    private void handleCaseCurrencyEmpty(boolean focused) {
        if (focused) {
            if (getText().toString().isEmpty()) {
                setText(prefix);
            }
        } else {
            if (getText().toString().equals(prefix)) {
                setText("");
            }
        }
    }

    private static class CurrencyTextWatcher implements TextWatcher {
        private final EditText editText;
        private String previousCleanString;
        private String prefix;

        CurrencyTextWatcher(EditText editText, String prefix) {
            this.editText = editText;
            this.prefix = prefix;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            // do nothing
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // do nothing
        }

        @Override
        public void afterTextChanged(Editable editable) {
            String str = editable.toString();
            if (str.length() < prefix.length()) {
                editText.setText(prefix);
                editText.setSelection(prefix.length());
                return;
            }
            if (str.equals(prefix)) {
                return;
            }
            // cleanString this the string which not contain prefix and ,
            String cleanString = str.replace(prefix, "").replaceAll("[,]", "");
            // for prevent afterTextChanged recursive call
            if (cleanString.equals(previousCleanString) || cleanString.isEmpty()) {
                return;
            }
            previousCleanString = cleanString;

            String formattedString;
            if (cleanString.contains(".")) {
                formattedString = formatDecimal(cleanString);
            } else {
                formattedString = formatInteger(cleanString);
            }
            editText.removeTextChangedListener(this); // Remove listener
            editText.setText(formattedString);
            handleSelection();
            editText.addTextChangedListener(this); // Add back the listener
        }

        private String formatInteger(String str) {
            BigDecimal parsed = new BigDecimal(str);
            DecimalFormat formatter =
                    new DecimalFormat(prefix + "#,###", new DecimalFormatSymbols(Locale.US));
            return formatter.format(parsed);
        }

        private String formatDecimal(String str) {
            if (str.equals(".")) {
                return prefix + ".";
            }
            BigDecimal parsed = new BigDecimal(str);
            // example pattern VND #,###.00
            DecimalFormat formatter = new DecimalFormat(prefix + "#,###." + getDecimalPattern(str),
                    new DecimalFormatSymbols(Locale.US));
            formatter.setRoundingMode(RoundingMode.DOWN);
            return formatter.format(parsed);
        }

        /**
         * It will return suitable pattern for format decimal
         * For example: 10.2 -> return 0 | 10.23 -> return 00, | 10.235 -> return 000
         */
        private String getDecimalPattern(String str) {
            int decimalCount = str.length() - str.indexOf(".") - 1;
            StringBuilder decimalPattern = new StringBuilder();
            for (int i = 0; i < decimalCount && i < MAX_DECIMAL; i++) {
                decimalPattern.append("0");
            }
            return decimalPattern.toString();
        }

        private void handleSelection() {
            if (editText.getText().length() <= MAX_LENGTH) {
                editText.setSelection(editText.getText().length());
            } else {
                editText.setSelection(MAX_LENGTH);
            }
        }
    }
}

এটি এক্সএমএলে পছন্দ মতো ব্যবহার করুন

 <...CurrencyEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

আপনার প্রকল্পের জন্য উপযুক্ত জন্য আপনার নীচে 2 ধ্রুবক সম্পাদনা করা উচিত

private static String prefix = "VND ";
private static final int MAX_DECIMAL = 3;

এখানে চিত্র বর্ণনা লিখুন

গিথুবে ডেমো


4
এটা অসাধারণ!
YTerle

4
আমি দেখতে পেলাম যে টাইপ করার পরে দশমিক জায়গায় সর্বাধিক সংখ্যায় পৌঁছানোর জন্য, 5-9 নম্বরের প্রবেশের চেষ্টা করা শেষ দশমিক স্থানটি 1 দ্বারা বাড়িয়ে দেবে ... এটি বৃত্তাকার! আমার ফিক্স ডাকতে ছিল formatter.setRoundingMode(RoundingMode.DOWN);মধ্যে formatDecimalপদ্ধতি।
বি.ডব্লু

@ বাইবিক্স সমস্যাটি সন্ধানের জন্য আপনাকে অনেক ধন্যবাদ। আমি আপনার সম্পাদনাটি অনুমোদন করেছি
ফান ভ্যান লিনহ

কীভাবে ভিএনডি-র মুদ্রা প্রতীক স্থাপন করা যায় ??
ময়ূর করমুর

4
আরেকটি উন্নতি ধারণা: যদি ব্যবহারকারী প্রবেশ করে $., যখন আমরা কাঁচা মান পাই .এবং ডাবলকে বিশ্লেষণ করি, এটি এনএফই দেয়। ফিক্স করার জন্য, আমি তৈরি formatDecimal()রিটার্ন prefix + "0.";এবং পরিবর্তন #,###.করার জন্য #,##0.ভিতরে formatDecimal()। কেবলমাত্র দশমিক স্থানে ব্যবহারকারী প্রবেশ করলে এটি আরও ভাল দেখায়। এটি $0.25পরিবর্তে হিসাবে দেখায় $.25
গোখন আরিক

13

আসলে, আগে সরবরাহ করা সমাধান কাজ করছে না। আপনি 100.00 লিখতে চাইলে এটি কাজ করে না।

প্রতিস্থাপন:

double parsed = Double.parseDouble(cleanString);
String formato = NumberFormat.getCurrencyInstance().format((parsed/100));

সঙ্গে:

BigDecimal parsed = new BigDecimal(cleanString).setScale(2,BigDecimal.ROUND_FLOOR).divide(new BigDecimal(100),BigDecimal.ROUND_FLOOR);                
String formato = NumberFormat.getCurrencyInstance().format(parsed);

আমার অবশ্যই বলতে হবে যে আমি আমার কোডের জন্য কিছু পরিবর্তন করেছি। জিনিসটি হ'ল আপনার বিগডিসিমাল ব্যবহার করা উচিত


6

আমি ব্রাজিল মুদ্রার ফর্ম্যাটগুলি ব্যবহার করতে এবং মান সম্পাদনা করার সময় কার্সারের অবস্থান সামঞ্জস্য করে টেক্সট ওয়াচারের প্রয়োগগুলি সহ ক্লাসটি পরিবর্তন করি।

পাবলিক ক্লাসের মানি টেক্সট ওয়াচচার টেক্সটওয়াটার প্রয়োগ করে {

    ব্যক্তিগত সম্পাদনা পাঠ্য সম্পাদনা পাঠ;

    প্রাইভেট স্ট্রিং লাস্টঅ্যামাউন্ট = "";

    প্রাইভেট ইন লাস্ট কার্সরপজিশন = -1;

    পাবলিক মানিটেক্সট ওয়াচার (এডিট টেক্সট এডিট টেক্সট) {
        সুপার();
        this.editText = editText;
    }

    @অগ্রাহ্য করা
    টেক্সটচেনজড পাবলিক অকার্যকর (চারসেকেন্সের পরিমাণ, ইনট স্টার্ট, ইন্টের আগে, ইন্ট গণনা) {

        যদি (! পরিমাণ.toString ()। সমান (সর্বশেষ পরিমাণ)) {

            স্ট্রিং ক্লিনস্ট্রিং = ক্লিয়ারিকেন্সিটিওনম্বার (পরিমাণ. টো স্ট্রিং ());

            চেষ্টা করুন

                স্ট্রিং ফর্ম্যাটডঅ্যামাউন্ট = ট্রান্সফর্মটোকোয়ারન્સી (ক্লিনস্ট্রিং);
                editText.removeTextChangedListener (এটি);
                editText.setText (ফর্ম্যাটডঅ্যামাউন্ট);
                editText.setSeલેક્શન (ফর্ম্যাটডঅ্যামাউন্ট। দৈর্ঘ্য ());
                editText.addTextChangedListener (এটি);

                যদি (সর্বশেষ কার্সারপজিশন! = শেষঅ্যামাউন্ট.লেন্থ () && সর্বশেষ কার্সর অবস্থান! = -1)
                    int দৈর্ঘ্যডেল্টা = formattedAmount.leth () - lastAmount.length ();
                    int newCursorOffset = সর্বাধিক (0, মিনিট (ফর্ম্যাটড্যামাউন্ট। দৈর্ঘ্য (), সর্বশেষ কার্সর অবস্থান + দৈর্ঘ্যডেল্টা));
                    editText.setSelection (newCursorOffset);
                }
            } ধরা (ব্যতিক্রম ই) {
               // কিছু লগ
            }
        }
    }

    @অগ্রাহ্য করা
    টেক্সট চ্যাঞ্জড (সম্পাদনাযোগ্য) এর পরে সর্বজনীন শূন্য {
    }

    @অগ্রাহ্য করা
    টেক্সটচেন্জেডের আগে সর্বজনীন শূন্যতা (চারসেকেন্ডস, ইনট স্টার্ট, ইনট কাউন্ট, ইনট পরে) {
        স্ট্রিং মান = s.toString ();
        যদি (! value.equals ("")) {
            স্ট্রিং ক্লিনস্ট্রিং = ক্লিয়ারিকেন্সিটিও নাম্বার (মান);
            স্ট্রিং ফর্ম্যাটডঅ্যামাউন্ট = ট্রান্সফর্মটোকোয়ারન્સી (ক্লিনস্ট্রিং);
            lastAmount = formattedAmount;
            সর্বশেষ কার্সরপজিশন = editText.getSelectionStart ();
        }
    }

    পাবলিক স্ট্যাটিক স্ট্রিং ক্লিয়ার কার্টেন্সি টু নাম্বার (স্ট্রিং কারেন্সিভ্যালু) {
        স্ট্রিং ফলাফল = নাল;

        যদি (কারেন্সিভ্যালু == নাল) {
            ফলাফল = "";
        } অন্য {
            ফলাফল = মুদ্রাভ্যালু.রেপসএল ("[(আজ) | (এজেড)) | ($ ,.)]", "");
        }
        প্রত্যাবর্তনের ফলাফল;
    }

    সার্বজনীন স্ট্যাটিক বুলিয়ান হল কারঙ্কেন্সিভ্যালু (স্ট্রিং কারেন্সিভ্যালু, বুলিয়ান পোডসারজিওর) {
        বুলিয়ান ফলাফল;

        যদি (কারেন্সিভ্যালু == নাল || মুদ্রাভ্যালিউ.লেন্থ () == 0)
            ফলাফল = মিথ্যা;
        } অন্য {
            যদি (! পোডসারজিওর && মুদ্রা ভ্যালু.ইকুয়ালস ("0,00")) {
                ফলাফল = মিথ্যা;
            } অন্য {
                ফলাফল = সত্য;
            }
        }
        প্রত্যাবর্তনের ফলাফল;
    }

    পাবলিক স্ট্যাটিক স্ট্রিং ট্রান্সফর্মটিক্রান্সিয়েন্স (স্ট্রিং মান) {
        ডাবল পার্সড = ডাবল. পার্সডুবল (মান);
        স্ট্রিং ফর্ম্যাটেড = নাম্বার ফর্ম্যাট.জেট কারেন্সিআইস্ট্যান্স (নতুন লোকেল ("পিটি", "বিআর"))। ফর্ম্যাট ((পার্সড / 100));
        বিন্যাসিত = formatted.replaceAll ("[^ (0-9) (।,)]" "," ");
        ফর্ম্যাটেড রিটার্ন;
    }
}

এই লাইনে "int newCursorOffset = সর্বাধিক (0, মিনিট (ফর্ম্যাটড্যামাউন্ট। দৈর্ঘ্য (), সর্বশেষ কার্সার অবস্থান + দৈর্ঘ্যডেল্টা));" সর্বোচ্চ ও সর্বনিম্ন কোন ধরণের অবজেক্ট?
আর্থার মেলো

4
@ আর্থার মেলো ইটস, ম্যাথ.ম্যাক্স, ম্যাথ.মিন কোডটি ধন্যবাদ জানায় এবং এডিটেক্সট থেকে কমা অপসারণ করার সময় এটি ব্যর্থ বলে মনে হচ্ছে।
মার্কোস ভাসকনস্লোস

4

আমি গিলের্মিস উত্তরে তৈরি করেছি, তবে আমি কার্সারের অবস্থান সংরক্ষণ করি এবং পিরিয়ডগুলিও আলাদাভাবে আচরণ করি - এইভাবে যদি কোনও ব্যবহারকারী পিরিয়ড পরে টাইপ করে থাকে তবে এটি পিরিয়ডের আগে সংখ্যাগুলিকে প্রভাবিত করে না আমি এটি দেখতে পাই যে এটি একটি খুব মসৃণ ইনপুট দেয় ।

    [yourtextfield].addTextChangedListener(new TextWatcher()
    {
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
        private String current = "";

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
            if(!s.toString().equals(current))
            {
                   [yourtextfield].removeTextChangedListener(this);

                   int selection = [yourtextfield].getSelectionStart();


                   // We strip off the currency symbol
                   String replaceable = String.format("[%s,\\s]", NumberFormat.getCurrencyInstance().getCurrency().getSymbol());
                   String cleanString = s.toString().replaceAll(replaceable, "");

                   double price;

                   // Parse the string                     
                   try
                   {
                       price = Double.parseDouble(cleanString);
                   }
                   catch(java.lang.NumberFormatException e)
                   {
                       price = 0;
                   }

                   // If we don't see a decimal, then the user must have deleted it.
                   // In that case, the number must be divided by 100, otherwise 1
                   int shrink = 1;
                   if(!(s.toString().contains(".")))
                   {
                       shrink = 100;
                   }

                   // Reformat the number
                   String formated = currencyFormat.format((price / shrink));

                   current = formated;
                   [yourtextfield].setText(formated);
                   [yourtextfield].setSelection(Math.min(selection, [yourtextfield].getText().length()));

                   [yourtextfield].addTextChangedListener(this);
                }
        }


        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after)
        {

        }


        @Override
        public void afterTextChanged(Editable s)
        {
        }
    });

এটা আমার অনেক সাহায্য। আপনাকে ধন্যবাদ @ জেনিক্সপ্রো
হ্যারিন কাক্লোটার

আমি আপনার ধারণাটি পছন্দ করি তবে এটি যদি আপনি কার্সারের পরে অঙ্কের সংখ্যাটি সংরক্ষণ করেন তবে এটি স্নিগ্ধ মনে হচ্ছে, তারপরে সেলেকশন (দৈর্ঘ্য - পরে) সেট করুন।
আলফা হুয়াং

অনেক আগ্রহব্যাঞ্জক! আমার শারীরিক ডিভাইসে প্রতিস্থাপনযোগ্য ব্যবহার করে , তবে এটি এমুলেটরটিতে কাজ করে না।
অ্যালিটন অলিভিরা

4

যদিও এখানে উত্তর প্রচুর আছে, আমি এই কোড যে আমি পাওয়া ভাগ করে নিতে চাই এখানে যেহেতু আমি তার সবচেয়ে জোরালো এবং পরিষ্কার উত্তর বিশ্বাস করি।

class CurrencyTextWatcher implements TextWatcher {

    boolean mEditing;

    public CurrencyTextWatcher() {
        mEditing = false;
    }

    public synchronized void afterTextChanged(Editable s) {
        if(!mEditing) {
            mEditing = true;

            String digits = s.toString().replaceAll("\\D", "");
            NumberFormat nf = NumberFormat.getCurrencyInstance();
            try{
                String formatted = nf.format(Double.parseDouble(digits)/100);
                s.replace(0, s.length(), formatted);
            } catch (NumberFormatException nfe) {
                s.clear();
            }

            mEditing = false;
        }
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

    public void onTextChanged(CharSequence s, int start, int before, int count) { }

}

আশা করি এটা সাহায্য করবে.


দশমিক বিন্দু যে স্ট্রিপ না হবে? তাহলে আপনি $ 100.00 এবং 10,000 ডলারের মধ্যে পার্থক্য বলতে সক্ষম হবেন না - যদি না আমি কিছু মিস করি।
ন্যাশ

4
এই নিখুঁত উত্তর! আমার জন্য কাজ। আমার, কেবলমাত্র এই উত্তরগুলিতে আমি কতটা সময় ব্যয় করেছি এবং অবশেষে নীচে স্ক্রোল করেছিলাম এবং আমি যা চাই তা পেয়েছি about
জি রং

আমি আনন্দিত এটি আপনাকে সাহায্য করেছে।
কেভান এন

@ ন্যাশ এটি একটি টেক্সট ওয়াচার এবং এটি পাঠ্যটিকে ব্যবহারকারী প্রকার হিসাবে ফর্ম্যাট করে যা আপনার উল্লিখিত কেসটিকে বাধা দেয়।
কায়ভান এন

@ কেভানএন আমি জানি টেক্সট ওয়াচার কী। replaceAll("\\D", "")অঙ্ক নয় এমন সমস্ত কিছুই মুছে ফেলবে, সুতরাং "$ 100.00" এবং "$ 10,000" উভয়ই "10000" হয়ে উঠবে। দেখে মনে হচ্ছে আপনি সেন্ট অন্তর্ভুক্ত করতে ইনপুটটি গণনা করছেন। সুতরাং যদি এটির গ্যারান্টিযুক্ত, দুর্দান্ত তবে আমি যদি না মনে করি যে সমস্যা হতে চলেছে।
nasch

4

ঠিক আছে, মুদ্রার ফর্ম্যাটগুলি, মুছুন-পশ্চাদপটে কীস্ট্রোকটি মোকাবেলার জন্য এখানে আরও ভাল উপায়। কোডটি উপরের @ অ্যান্ড্রয়েডকুরিয়াস 'কোডের উপর ভিত্তি করে ... তবে, পিছনের দিক থেকে মুছে ফেলা এবং কিছু পার্স ব্যতিক্রম সম্পর্কিত কিছু সমস্যা রয়েছে: http://miguelt.blogspot.ca/2013/01/textwatcher-for-currency-masksformatting .html [আপডেট] আগের সমাধানটিতে কিছু সমস্যা ছিল ... এটি একটি ভাল দ্রাবকতা: http://miguelt.blogspot.ca/2013/02/update-textwatcher-for-currency.html এবং ... এখানে বিশদ:

এটি প্রচলিত অ্যান্ড্রয়েড প্রক্রিয়াগুলি ব্যবহার করার কারণে এই পদ্ধতিটি আরও ভাল। ব্যবহারকারীর ভিউটি উপস্থিত থাকার পরে মানগুলি ফর্ম্যাট করা উচিত।

সংখ্যার মানগুলিকে সীমাবদ্ধ করতে একটি ইনপুটফিল্টার সংজ্ঞায়িত করুন - এটি বেশিরভাগ ক্ষেত্রেই প্রয়োজন কারণ দীর্ঘ স্ক্রিনটি সম্পাদনা করার জন্য পর্দা যথেষ্ট বড় নয়। এটি একটি স্থির অভ্যন্তর শ্রেণি বা অন্য কোনও সাধারণ শ্রেণি হতে পারে:

/** Numeric range Filter. */
class NumericRangeFilter implements InputFilter {
    /** Maximum value. */
    private final double maximum;
    /** Minimum value. */
    private final double minimum;
    /** Creates a new filter between 0.00 and 999,999.99. */
    NumericRangeFilter() {
        this(0.00, 999999.99);
    }
    /** Creates a new filter.
     * @param p_min Minimum value.
     * @param p_max Maximum value. 
     */
    NumericRangeFilter(double p_min, double p_max) {
        maximum = p_max;
        minimum = p_min;
    }
    @Override
    public CharSequence filter(
            CharSequence p_source, int p_start,
            int p_end, Spanned p_dest, int p_dstart, int p_dend
    ) {
        try {
            String v_valueStr = p_dest.toString().concat(p_source.toString());
            double v_value = Double.parseDouble(v_valueStr);
            if (v_value<=maximum && v_value>=minimum) {
                // Returning null will make the EditText to accept more values.
                return null;
            }
        } catch (NumberFormatException p_ex) {
            // do nothing
        }
        // Value is out of range - return empty string.
        return "";
    }
}

একটি শ্রেণি সংজ্ঞায়িত করুন (অভ্যন্তরীণ স্থিতিশীল বা কেবলমাত্র একটি শ্রেণি) যা View.OnFocusChangeListener প্রয়োগ করবে। নোট করুন যে আমি একটি ইউটিলস ক্লাস ব্যবহার করছি - বাস্তবায়নটি "পরিমাণ, কর" এ পাওয়া যাবে।

/** Used to format the amount views. */
class AmountOnFocusChangeListener implements View.OnFocusChangeListener {
    @Override
    public void onFocusChange(View p_view, boolean p_hasFocus) {
        // This listener will be attached to any view containing amounts.
        EditText v_amountView = (EditText)p_view;
        if (p_hasFocus) {
            // v_value is using a currency mask - transfor over to cents.
            String v_value = v_amountView.getText().toString();
            int v_cents = Utils.parseAmountToCents(v_value);
            // Now, format cents to an amount (without currency mask)
            v_value = Utils.formatCentsToAmount(v_cents);
            v_amountView.setText(v_value);
            // Select all so the user can overwrite the entire amount in one shot.
            v_amountView.selectAll();
        } else {
            // v_value is not using a currency mask - transfor over to cents.
            String v_value = v_amountView.getText().toString();
            int v_cents = Utils.parseAmountToCents(v_value);
            // Now, format cents to an amount (with currency mask)
            v_value = Utils.formatCentsToCurrency(v_cents);
            v_amountView.setText(v_value);
        }
    }
}

এই শ্রেণিটি সম্পাদনা করার সময় মুদ্রার ফর্ম্যাটটি সরিয়ে ফেলবে - মানক প্রক্রিয়ার উপর নির্ভর করে। ব্যবহারকারী যখন প্রস্থান করেন, মুদ্রার ফর্ম্যাটটি পুনরায় প্রয়োগ করা হয়।

উদাহরণের সংখ্যা হ্রাস করার জন্য কিছু স্থির পরিবর্তনশীল সংজ্ঞায়িত করা ভাল:

   static final InputFilter[] FILTERS = new InputFilter[] {new NumericRangeFilter()};
   static final View.OnFocusChangeListener ON_FOCUS = new AmountOnFocusChangeListener();

অবশেষে, অনক্রিটভিউয়ের মধ্যে (...):

   EditText mAmountView = ....
   mAmountView.setFilters(FILTERS);
   mAmountView.setOnFocusChangeListener(ON_FOCUS);

আপনি সম্পাদনা পাঠের যে কোনও সংখ্যক ভিউতে ফিল্টার এবং ওএন_ফোকাস পুনরায় ব্যবহার করতে পারেন।

ইউটিলস শ্রেণি এখানে:

public class Utils {

   private static final NumberFormat FORMAT_CURRENCY = NumberFormat.getCurrencyInstance();
   /** Parses an amount into cents.
    * @param p_value Amount formatted using the default currency. 
    * @return Value as cents.
    */
   public static int parseAmountToCents(String p_value) {
       try {
           Number v_value = FORMAT_CURRENCY.parse(p_value);
           BigDecimal v_bigDec = new BigDecimal(v_value.doubleValue());
           v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
           return v_bigDec.movePointRight(2).intValue();
       } catch (ParseException p_ex) {
           try {
               // p_value doesn't have a currency format.
               BigDecimal v_bigDec = new BigDecimal(p_value);
               v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
               return v_bigDec.movePointRight(2).intValue();
           } catch (NumberFormatException p_ex1) {
               return -1;
           }
       }
   }
   /** Formats cents into a valid amount using the default currency.
    * @param p_value Value as cents 
    * @return Amount formatted using a currency.
    */
   public static String formatCentsToAmount(int p_value) {
       BigDecimal v_bigDec = new BigDecimal(p_value);
       v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
       v_bigDec = v_bigDec.movePointLeft(2);
       String v_currency = FORMAT_CURRENCY.format(v_bigDec.doubleValue());
       return v_currency.replace(FORMAT_CURRENCY.getCurrency().getSymbol(), "").replace(",", "");
   }
   /** Formats cents into a valid amount using the default currency.
    * @param p_value Value as cents 
    * @return Amount formatted using a currency.
    */
   public static String formatCentsToCurrency(int p_value) {
       BigDecimal v_bigDec = new BigDecimal(p_value);
       v_bigDec = v_bigDec.setScale(2, BigDecimal.ROUND_HALF_UP);
       v_bigDec = v_bigDec.movePointLeft(2);
       return FORMAT_CURRENCY.format(v_bigDec.doubleValue());
   }

}

যদিও এটি তাত্ত্বিকভাবে প্রশ্নের উত্তর দিতে পারে, আমরা চাই আপনি লিখিত নিবন্ধের প্রয়োজনীয় অংশগুলি আপনার উত্তরে অন্তর্ভুক্ত করুন এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করুন । এটি করতে ব্যর্থ হওয়ায় উত্তরটি লিঙ্ক পচা থেকে ঝুঁকিতে পড়ে।
কেভ

আমি java.lang.Number FormatException পেয়ে যাচ্ছি: অবৈধ ডাবল: "$ 12,345.00" সম্পাদনা পাঠ্য ফোকাস হারিয়ে ফেললে। কিভাবে ঠিক হবে এটা.
মাধন

4

আমি প্রয়োগটি নাথান লেইগ রেফারেন্স এবং কায়ভান এন এর এবং ব্যবহারকারীর 2582318 এর প্রস্তাবিত রেজেক্সটি নিম্নলিখিত সংস্করণটি তৈরি করার জন্য অঙ্ক বাদে সমস্ত অক্ষর অপসারণ করার জন্য ব্যবহার করেছি:

fun EditText.addCurrencyFormatter() {

    // Reference: /programming/5107901/better-way-to-format-currency-input-edittext/29993290#29993290
    this.addTextChangedListener(object: TextWatcher {

        private var current = ""

        override fun afterTextChanged(s: Editable?) {
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            if (s.toString() != current) {
                this@addCurrencyFormatter.removeTextChangedListener(this)
                // strip off the currency symbol

                // Reference for this replace regex: /programming/5107901/better-way-to-format-currency-input-edittext/28005836#28005836
                val cleanString = s.toString().replace("\\D".toRegex(), "")
                val parsed = if (cleanString.isBlank()) 0.0 else cleanString.toDouble()
                // format the double into a currency format
                val formated = NumberFormat.getCurrencyInstance()
                        .format(parsed / 100)

                current = formated
                this@addCurrencyFormatter.setText(formated)
                this@addCurrencyFormatter.setSelection(formated.length)

                this@addCurrencyFormatter.addTextChangedListener(this)
            }
        }
    })

}

এটি কোটলিনে একটি এক্সটেনশন ফাংশন যা এডিট টেক্সটের টেক্সটচ্যাঞ্জডলিস্টারে টেক্সটওয়াটারকে যুক্ত করে।

এটি ব্যবহার করার জন্য, ঠিক:

yourEditText = (EditText) findViewById(R.id.edit_text_your_id);
yourEditText.addCurrencyFormatter()

আমি আসা করি এটা সাহায্য করবে.


3

আমি থেকে এই পেয়েছিলাম এখানে এবং পর্তুগিজ মুদ্রা বিন্যাস অনুসরণ করে থাকতে এটিকে পরিবর্তন করেছেন।

import java.text.NumberFormat;
import java.util.Currency;
import java.util.Locale;

import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

public class CurrencyTextWatcher implements TextWatcher {

    private String current = "";
    private int index;
    private boolean deletingDecimalPoint;
    private final EditText currency;

    public CurrencyTextWatcher(EditText p_currency) {
        currency = p_currency;
    }


    @Override
    public void beforeTextChanged(CharSequence p_s, int p_start, int p_count, int p_after) {

        if (p_after>0) {
                index = p_s.length() - p_start;
            } else {
                index = p_s.length() - p_start - 1;
            }
            if (p_count>0 && p_s.charAt(p_start)==',') {
                deletingDecimalPoint = true;
            } else {
                deletingDecimalPoint = false;
            }

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable p_s) {


         if(!p_s.toString().equals(current)){
                currency.removeTextChangedListener(this);
                if (deletingDecimalPoint) {
                    p_s.delete(p_s.length()-index-1, p_s.length()-index);
                }
                // Currency char may be retrieved from  NumberFormat.getCurrencyInstance()
                String v_text = p_s.toString().replace("€","").replace(",", "");
                v_text = v_text.replaceAll("\\s", "");
                double v_value = 0;
                if (v_text!=null && v_text.length()>0) {
                    v_value = Double.parseDouble(v_text);
                }
                // Currency instance may be retrieved from a static member.
                NumberFormat numberFormat = NumberFormat.getCurrencyInstance(new Locale("pt", "PT"));
                String v_formattedValue = numberFormat.format((v_value/100));
                current = v_formattedValue;
                currency.setText(v_formattedValue);
                if (index>v_formattedValue.length()) {
                    currency.setSelection(v_formattedValue.length());
                } else {
                    currency.setSelection(v_formattedValue.length()-index);
                }
                // include here anything you may want to do after the formatting is completed.
                currency.addTextChangedListener(this);
             }
    }

}

লেআউট.এক্সএমএল

<EditText
    android:id="@+id/edit_text_your_id"
    ...
    android:text="0,00 €"
    android:inputType="numberDecimal"
    android:digits="0123456789" />

এটি কাজ পেতে

    yourEditText = (EditText) findViewById(R.id.edit_text_your_id);
    yourEditText.setRawInputType(Configuration.KEYBOARD_12KEY);
    yourEditText.addTextChangedListener(new CurrencyTextWatcher(yourEditText));

2

আমার জন্য এটি এইভাবে কাজ করে

 public void onTextChanged(CharSequence s, int start,
                    int before, int count) {
                if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
                {
                    String userInput= ""+s.toString().replaceAll("[^\\d]", "");
                    if (userInput.length() > 2) {
                        Float in=Float.parseFloat(userInput);
                        price = Math.round(in); // just to get an Integer
                        //float percen = in/100;
                        String first, last;
                        first = userInput.substring(0, userInput.length()-2);
                        last = userInput.substring(userInput.length()-2);
                        edEx1.setText("$"+first+"."+last);
                        Log.e(MainActivity.class.toString(), "first: "+first + " last:"+last);
                        edEx1.setSelection(edEx1.getText().length());
                    }
                }
            }

2

ইনপুটফিল্টার ইন্টারফেস ব্যবহার করা ভাল। রেজেেক্স ব্যবহার করে যে কোনও ধরণের ইনপুট পরিচালনা করা অনেক সহজ। মুদ্রার ইনপুট ফর্ম্যাটটির জন্য আমার সমাধান:

public class CurrencyFormatInputFilter implements InputFilter {

Pattern mPattern = Pattern.compile("(0|[1-9]+[0-9]*)(\\.[0-9]{1,2})?");

@Override
public CharSequence filter(
        CharSequence source,
        int start,
        int end,
        Spanned dest,
        int dstart,
        int dend) {

String result = 
        dest.subSequence(0, dstart)
        + source.toString() 
        + dest.subSequence(dend, dest.length());

Matcher matcher = mPattern.matcher(result);

if (!matcher.matches()) return dest.subSequence(dstart, dend);

return null;
}
}

বৈধ: 0.00, 0.0, 10.00, 111.1
অবৈধ: 0, 0.000, 111, 10, 010.00, 01.0

ব্যবহারবিধি:

editText.setFilters(new InputFilter[] {new CurrencyFormatInputFilter()});

1

আমি ব্যবহারকারীর মুদ্রায় প্রবেশ করতে এবং স্ট্রিং থেকে ইনটকে ডিবিতে সঞ্চয় করতে রূপান্তর করতে এবং ইন্ট থেকে আবার স্ট্রিংয়ে ফিরে পরিবর্তন করতে এটি ব্যবহার করেছি

https://github.com/nleigh/Restटका/blob/master/Restटका/src/uk/co/nathanleigh/restटका/Currency Format.java


আপনি কি আপনার উত্তরে মূল ধারণাগুলি অন্তর্ভুক্ত করতে পারেন? অন্যথায় এটি প্রায় একটি লিংক-উত্তর এবং এটি মুছে ফেলার ঝুঁকিতে রয়েছে ...
আলেকজান্ডার ভোগ্ট

1

যদি আপনার জসন মুদ্রার ক্ষেত্রটি সংখ্যার হয় (এবং স্ট্রিং নয়) তবে এটি 3.1, 3.15 বা মাত্র 3 হিসাবে আসতে পারে কারণ জসন স্বয়ংক্রিয়ভাবে নম্বর ক্ষেত্রগুলিকে গোল করে।

এক্ষেত্রে আপনার যথাযথ প্রদর্শনের জন্য এটি গোলাকার প্রয়োজন হতে পারে (এবং পরে কোনও ইনপুট ক্ষেত্রে কোনও মাস্ক ব্যবহার করতে সক্ষম হতে):

    NumberFormat nf = NumberFormat.getCurrencyInstance();

    float value = 200 // it can be 200, 200.3 or 200.37, BigDecimal will take care
    BigDecimal valueAsBD = BigDecimal.valueOf(value);
    valueAsBD.setScale(2, BigDecimal.ROUND_HALF_UP);

    String formated = nf.format(valueAsBD);

এটি কেন প্রয়োজন?

সমস্ত উত্তর মুদ্রা সিম্বলগুলি মুছে ফেলার দিকে নির্দেশ করে যখন বিচারগুলি টাইপ করার সময় আপনি সেন্টগুলি গ্রহণ করছেন এবং তাই ডোলার + সেন্ট / 100 = ডলার, সেন্ট গঠন করছেন। তবে যদি আপনার জসন মুদ্রার ক্ষেত্রটি কোনও সংখ্যার (এবং কোনও স্ট্রিং নয়) হয় তবে এটি আপনার সেন্টকে গোল করবে, এটি 3, 3.1 বা 3.15 হতে পারে।


4
ঠিক আমার যা প্রয়োজন ছিল। ধন্যবাদ!
এরিক এঙ্গেলহার্ট

come as 3.1 , 3.15 or just 3. Because json automatically round number fields- এটি গোলাকার সাথে সাধারণ কিছু পায় নি !
মার্সিন ওরোলোস্কি

1

অন্য পদ্ধতির, কিন্তু গিলহর্ম উত্তর উপর ভিত্তি করে । আপনার দেশের লোকেল উপলব্ধ না থাকলে বা আপনি যদি কাস্টম মুদ্রার চিহ্ন ব্যবহার করতে চান তবে এই পদ্ধতির ব্যবহারযোগ্য। এই বাস্তবায়নটি কেবলমাত্র ইতিবাচক অ-দশমিক।

এই কোড Kotlin, প্রথম প্রতিনিধি রয়েছে setMaskingMoneyজন্যEditText

fun EditText.setMaskingMoney(currencyText: String) {
    this.addTextChangedListener(object: MyTextWatcher{
        val editTextWeakReference: WeakReference<EditText> = WeakReference<EditText>(this@setMaskingMoney)
        override fun afterTextChanged(editable: Editable?) {
            val editText = editTextWeakReference.get() ?: return
            val s = editable.toString()
            editText.removeTextChangedListener(this)
            val cleanString = s.replace("[Rp,. ]".toRegex(), "")
            val newval = currencyText + cleanString.monetize()

            editText.setText(newval)
            editText.setSelection(newval.length)
            editText.addTextChangedListener(this)
        }
    })
}

তারপরে MyTextWatcherইন্টারফেসটি বাড়ানো উচিত TextWatcher। যেহেতু আমাদের কেবল afterTextChangedপদ্ধতি প্রয়োজন , তাই অন্যান্য পদ্ধতির এই ইন্টারফেসে ওভারাইড করা দরকার

interface MyTextWatcher: TextWatcher {
    override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
}

এবং নগদীকরণ পদ্ধতিগুলি হ'ল:

fun String.monetize(): String = if (this.isEmpty()) "0"
    else DecimalFormat("#,###").format(this.replace("[^\\d]".toRegex(),"").toLong())

সম্পূর্ণ বাস্তবায়ন:

fun EditText.setMaskingMoney(currencyText: String) {
    this.addTextChangedListener(object: MyTextWatcher{
        val editTextWeakReference: WeakReference<EditText> = WeakReference<EditText>(this@setMaskingMoney)
        override fun afterTextChanged(editable: Editable?) {
            val editText = editTextWeakReference.get() ?: return
            val s = editable.toString()
            editText.removeTextChangedListener(this)
            val cleanString = s.replace("[Rp,. ]".toRegex(), "")
            val newval = currencyText + cleanString.monetize()

            editText.setText(newval)
            editText.setSelection(newval.length)
            editText.addTextChangedListener(this)
        }
    })
}

interface MyTextWatcher: TextWatcher {
    override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
}


fun String.monetize(): String = if (this.isEmpty()) "0"
    else DecimalFormat("#,###").format(this.replace("[^\\d]".toRegex(),"").toLong())

এবং কোথাও অনক্রিট পদ্ধতিতে:

yourTextView.setMaskingMoney("Rp. ")

1

ডাবলস, বিগডিসিমালস এবং আরও অনেক কিছু নিয়ে খুব বেশি অনুসন্ধান এবং ব্যর্থ হওয়ার পরে, আমি এই কোডটি তৈরি করেছি। এটি প্লাগ এবং প্লে কাজ করে। এটি কোটলিনে সুতরাং, আমার মতো পোঁদে অন্যকে সহায়তা করার জন্য যেতে দিন।

কোডটি মূলত এমন একটি ফাংশন যা একটি টেক্সট ওয়াচার রাখবে এবং কোমাটিকে সঠিক জায়গায় সামঞ্জস্য করবে।

প্রথমে এই ফাংশনটি তৈরি করুন:

fun CurrencyWatcher( editText:EditText) {

    editText.addTextChangedListener(object : TextWatcher {
        //this will prevent the loop
        var changed: Boolean = false

        override fun afterTextChanged(p0: Editable?) {
            changed = false

        }

        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

            editText.setSelection(p0.toString().length)
        }

        @SuppressLint("SetTextI18n")
        override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            if (!changed) {
                changed = true

                var str: String = p0.toString().replace(",", "").trim()
                var element0: String = str.elementAt(0).toString()
                var element1: String = "x"
                var element2: String = "x"
                var element3: String = "x"
                var element4: String = "x"
                var element5: String = "x"
                var element6: String = "x"

                //this variables will store each elements of the initials data for the case we need to move this numbers like: 0,01 to 0,11 or 0,11 to 0,01
                if (str.length >= 2) {
                    element1 = str.elementAt(1).toString()
                }
                if (str.length >= 3) {
                    element2 = str.elementAt(2).toString()
                }

                editText.removeTextChangedListener(this)


                //this first block of code will take care of the case
                //where the number starts with 0 and needs to adjusta the 0 and the "," place
                if (str.length == 1) {
                    str = "0,0" + str
                    editText.setText(str)

                } else if (str.length <= 3 && str == "00") {

                    str = "0,00"
                    editText.setText(str)
                    editText.setSelection(str.length)
                } else if (element0 == "0" && element1 == "0" && element2 == "0") {
                    str = str.replace("000", "")
                    str = "0,0" + str
                    editText.setText(str)
                } else if (element0 == "0" && element1 == "0" && element2 != "0") {
                    str = str.replace("00", "")
                    str = "0," + str
                    editText.setText(str)
                } else {

                    //This block of code works with the cases that we need to move the "," only because the value is bigger
                    //lets get the others elements
                    if (str.length >= 4) {
                        element3 = str.elementAt(3).toString()
                    }
                    if (str.length >= 5) {
                        element4 = str.elementAt(4).toString()
                    }
                    if (str.length >= 6) {
                        element5 = str.elementAt(5).toString()
                    }
                    if (str.length == 7) {
                        element6 = str.elementAt(6).toString()
                    }


                    if (str.length >= 4 && element0 != "0") {

                        val sb: StringBuilder = StringBuilder(str)
                        //set the coma in right place
                        sb.insert(str.length - 2, ",")
                        str = sb.toString()
                    }

                    //change the 0,11 to 1,11
                    if (str.length == 4 && element0 == "0") {

                        val sb: StringBuilder = StringBuilder(str)
                        //takes the initial 0 out
                        sb.deleteCharAt(0);
                        str = sb.toString()

                        val sb2: StringBuilder = StringBuilder(str)
                        sb2.insert(str.length - 2, ",")
                        str = sb2.toString()
                    }

                    //this will came up when its like 11,11 and the user delete one, so it will be now 1,11
                    if (str.length == 3 && element0 != "0") {
                        val sb: StringBuilder = StringBuilder(str)
                        sb.insert(str.length - 2, ",")
                        str = sb.toString()
                    }

                    //came up when its like 0,11 and the user delete one, output will be 0,01
                    if (str.length == 2 && element0 == "0") {
                        val sb: StringBuilder = StringBuilder(str)
                        //takes 0 out
                        sb.deleteCharAt(0);
                        str = sb.toString()

                        str = "0,0" + str

                    }

                    //came up when its 1,11 and the user delete, output will be 0,11
                    if (str.length == 2 && element0 != "0") {
                        val sb: StringBuilder = StringBuilder(str)
                        //retira o 0 da frente
                        sb.insert(0, "0,")
                        str = sb.toString()

                    }


                    editText.setText(str)
                }

                //places the selector at the end to increment the number
                editText.setSelection(str.length)
                editText.addTextChangedListener(this)
            }

        }
    })
}

এবং তারপরে আপনি এই ফাংশনটিকে এভাবে কল করেন

val etVal:EditText = findViewById(R.id.etValue)

CurrencyWatcher(etVal)

0

বিভিন্ন উপায়ে উপর Stackoverflow পোস্টের মধ্যে সবচেয়ে দেখার পরও কি এই একটি ব্যবহার অর্জন করা TextWatcher, InputFilterবা এগুলির মতো গ্রন্থাগার CurrencyEditText আমি এই সহজ সমাধান উপর একটি ব্যবহার বসতি স্থাপন করে থাকেন OnFocusChangeListener

যুক্তিটি হ'ল EditTextযখন এটি ফোকাস হয় তখন কোনও সংখ্যাকে পার্স করা এবং ফোকাস হারিয়ে ফিরলে ফর্ম্যাট করে।

amount.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            Number numberAmount = 0f;
            try {
                numberAmount = Float.valueOf(amount.getText().toString());
            } catch (NumberFormatException e1) {
                e1.printStackTrace();
                try {
                    numberAmount = NumberFormat.getCurrencyInstance().parse(amount.getText().toString());
                } catch (ParseException e2) {
                    e2.printStackTrace();
                }
            }
            if (hasFocus) {
                amount.setText(numberAmount.toString());
            } else {
                amount.setText(NumberFormat.getCurrencyInstance().format(numberAmount));
            }
        }
    });

0

আমি একটি কোটলিন + আরএক্স সংস্করণ প্রয়োগ করেছি।

এটি ব্রাজিলিয়ান মুদ্রার জন্য (যেমন 1,500.00 - 5,21 - 192,90) তবে আপনি সহজেই অন্যান্য ফর্ম্যাটগুলির জন্য মানিয়ে নিতে পারেন।

আশা করি অন্য কাউকে এটি সহায়ক বলে মনে হয়েছে।

RxTextView
            .textChangeEvents(fuel_price) // Observe text event changes
            .filter { it.text().isNotEmpty() } // do not accept empty text when event first fires
            .flatMap {
                val onlyNumbers = Regex("\\d+").findAll(it.text()).fold(""){ acc:String,it:MatchResult -> acc.plus(it.value)}
                Observable.just(onlyNumbers)
            }
            .distinctUntilChanged()
            .map { it.trimStart('0') }
            .map { when (it.length) {
                        1-> "00"+it
                        2-> "0"+it
                        else -> it }
            }
            .subscribe {
                val digitList = it.reversed().mapIndexed { i, c ->
                    if ( i == 2 ) "${c},"
                    else if ( i < 2 ) c
                    else if ( (i-2)%3==0 ) "${c}." else c
                }

                val currency = digitList.reversed().fold(""){ acc,it -> acc.toString().plus(it) }
                fuel_price.text = SpannableStringBuilder(currency)
                fuel_price.setSelection(currency.length)
            }

0

কারেন্সিটেক্সট ওয়াচার.জভা

public class CurrencyTextWatcher implements TextWatcher {

    private final static String DS = "."; //Decimal Separator
    private final static String TS = ","; //Thousands Separator
    private final static String NUMBERS = "0123456789"; //Numbers
    private final static int MAX_LENGTH = 13; //Maximum Length

    private String format;

    private DecimalFormat decimalFormat;
    private EditText editText;

    public CurrencyTextWatcher(EditText editText) {
        String pattern = "###" + TS + "###" + DS + "##";
        decimalFormat = new DecimalFormat(pattern);
        this.editText = editText;
        this.editText.setInputType(InputType.TYPE_CLASS_NUMBER);
        this.editText.setKeyListener(DigitsKeyListener.getInstance(NUMBERS + DS));
        this.editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)});
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {

        editText.removeTextChangedListener(this);
        String value = editable.toString();
        if (!value.isEmpty()) {
            value = value.replace(TS, "");
            try {
                format = decimalFormat.format(Double.parseDouble(value));
                format = format.replace("0", "");
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }

            editText.setText(format);
        }

        editText.addTextChangedListener(this);
    }
}

এডিটটেক্সট্রাকেন্সি.জভা

public class EditTextCurrency extends AppCompatEditText {
    public EditTextCurrency(Context context) {
        super(context);
    }

    public EditTextCurrency(Context context, AttributeSet attrs) {
        super(context, attrs);
        addTextChangedListener(new CurrencyTextWatcher(this));
    }
}

এখানে চিত্র বর্ণনা লিখুন


0

এখানে আমি কীভাবে সম্পাদনা পাঠ্যে এমন একটি মুদ্রা প্রদর্শন করতে সক্ষম হয়েছি যা কার্যকর করা সহজ ছিল এবং সমস্ত জায়গাতে পাগল চিহ্নগুলির সম্ভাবনা ছাড়াই ব্যবহারকারীর পক্ষে ভাল কাজ করে। এডিটেক্সটটির আর ফোকাস না হওয়া পর্যন্ত এটি কোনও বিন্যাস করার চেষ্টা করবে না। ব্যবহারকারীর এখনও ফিরে যেতে পারেন এবং বিন্যাস বিনষ্ট না করে কোনও সম্পাদনা করতে পারেন। আমি কেবল প্রদর্শনের জন্য 'ফর্ম্যাটডপ্রিস' ভেরিয়েবল এবং গণনার জন্য আমি যে মূল্য সঞ্চয় / ব্যবহার করি তা হিসাবে 'আইটেমপ্রিস' ভেরিয়েবল ব্যবহার করি।

এটি সত্যিই ভালভাবে কাজ করছে বলে মনে হচ্ছে, তবে আমি কেবল কয়েক সপ্তাহের জন্য এখানে এসেছি, সুতরাং কোনও গঠনমূলক সমালোচনা একেবারে স্বাগত!

এক্সএমএল এডিটেক্সট ভিউতে নিম্নলিখিত বৈশিষ্ট্য রয়েছে:

android:inputType="numberDecimal"

গ্লোবাল ভেরিয়েবল:

private String formattedPrice;
private int itemPrice = 0;

অনক্রিট পদ্ধতিতে:

EditText itemPriceInput = findViewById(R.id.item_field_price);

itemPriceInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        String priceString = itemPriceInput.getText().toString();

        if (! priceString.equals("")) {
            itemPrice = Double.parseDouble(priceString.replaceAll("[$,]", ""));
            formattedPrice = NumberFormat.getCurrencyInstance().format(itemPrice);
            itemPriceInput.setText(formattedPrice);
        }
    }
});

0

যদি কেউ আরএক্সবাইন্ডিং এবং কোটলিন ব্যবহার করে এটি করার কোনও পদ্ধতিতে আগ্রহী হয়:

var isEditing = false

RxTextView.textChanges(dollarValue)
            .filter { !isEditing }
            .filter { it.isNotBlank() }
            .map { it.toString().filter { it.isDigit() } }
            .map { BigDecimal(it).setScale(2, BigDecimal.ROUND_FLOOR).divide(100.toBigDecimal(), BigDecimal.ROUND_FLOOR) }
            .map { NumberFormat.getCurrencyInstance(Locale("pt", "BR")).format(it) }
            .subscribe {
                isEditing = true
                dollarValue.text = SpannableStringBuilder(it)
                dollarValue.setSelection(it.length)
                isEditing = false
            }

0

অনুমোদিত উত্তরের জন্য কেবল একটি অতিরিক্ত মন্তব্য। পার্সিংয়ের কারণে এডিটেক্সট ফিল্ডে কার্সারটি সরানোর সময় আপনি ক্র্যাশ পেতে পারেন। আমি চেষ্টা করার চেষ্টা করার একটি বিবৃতি দিয়েছি, তবে নিজের কোডটি প্রয়োগ করেছি।

@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(!s.toString().equals(current)){
        amountEditText.removeTextChangedListener(this);

            String cleanString = s.toString().replaceAll("[$,.]", "");

            try{
                double parsed = Double.parseDouble(cleanString);
                String formatted = NumberFormat.getCurrencyInstance().format((parsed/100));
                current = formatted;
                amountEditText.setText(formatted);
                amountEditText.setSelection(formatted.length());
            } catch (Exception e) {

            }

            amountEditText.addTextChangedListener(this);
        }
    }

0

আপনি এই পদ্ধতিগুলি ব্যবহার করতে পারেন

import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import android.widget.TextView
import java.text.NumberFormat
import java.util.*

fun TextView.currencyFormat() {
    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {}

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            removeTextChangedListener(this)
            text = if (s?.toString().isNullOrBlank()) {
                ""
            } else {
                s.toString().currencyFormat()
            }
            if(this@currencyFormat is EditText){
                setSelection(text.toString().length)
            }
            addTextChangedListener(this)
        }
    })
}

fun String.currencyFormat(): String {
    var current = this
    if (current.isEmpty()) current = "0"
    return try {
        if (current.contains('.')) {
            NumberFormat.getNumberInstance(Locale.getDefault()).format(current.replace(",", "").toDouble())
        } else {
            NumberFormat.getNumberInstance(Locale.getDefault()).format(current.replace(",", "").toLong())
        }
    } catch (e: Exception) {
        "0"
    }
}

0

কোটলিন সংস্করণ:

    var current = ""

    editText.addTextChangedListener(object: TextWatcher {
        override fun afterTextChanged(s: Editable?) {}
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            val stringText = s.toString()

            if(stringText != current) {
                editText.removeTextChangedListener(this)

                val locale: Locale = Locale.UK
                val currency = Currency.getInstance(locale)
                val cleanString = stringText.replace("[${currency.symbol},.]".toRegex(), "")
                val parsed = cleanString.toDouble()
                val formatted = NumberFormat.getCurrencyInstance(locale).format(parsed / 100)

                current = formatted
                editText.setText(formatted)
                editText.setSelection(formatted.length)
                editText.addTextChangedListener(this)
            }
        }
    })

0
public class MoneyEditText extends android.support.v7.widget.AppCompatEditText{
public MoneyEditText(Context context) {
    super(context);
    addTextChangedListener(MoneySplitter());
}
public MoneyEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    addTextChangedListener(MoneySplitter());
}
public MoneyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    addTextChangedListener(MoneySplitter());
}
public TextWatcher MoneySplitter() {
    TextWatcher textWatcher = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            try
            {
                removeTextChangedListener(this);
                String value = s.toString();
                if (!value.equals(""))
                {
                        if(!TextUtils.isEmpty(value))
                            setText(formatPrice(Double.parseDouble(value)));
                        setSelection(getText().toString().length());

                }
                addTextChangedListener(this);
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                addTextChangedListener(this);
            }
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }
        @Override
        public void afterTextChanged(Editable s) {
        }
    };
    return textWatcher;
}

public static String formatPrice(double value){
        int DecimalPointNumber = 2;
        Locale locale = Locale.getDefault();
        DecimalFormat myFormatter = (DecimalFormat) NumberFormat.getCurrencyInstance(locale);
        StringBuilder sb = new StringBuilder();
        if(DecimalPointNumber>0){
            for (int i = 0; i < DecimalPointNumber; i++) {
                sb.append("#");
            }
            myFormatter.applyPattern("###,###."+ sb.toString());
        }else
            myFormatter.applyPattern("###,###"+ sb.toString());

            return Currency.getInstance(Locale.getDefault()).getSymbol() + myFormatter.format(value);
    }
}

এবং তারপরে আপনার সম্পাদনা পাঠ হিসাবে এই ব্লকটি ব্যবহার করুন

   <MoneyEditText
   android:id="@+id/txtPrice"
   android:layout_width="match_parent"
   android:layout_height="64dp"
   android:digits="0123456789.,"
   android:inputType="numberDecimal"
   android:selectAllOnFocus="true"
   android:singleLine="true" />

আপনি যেমন চান তেমন ইনপুট পাঠ্য বিন্যাস করার জন্য এই কাস্টমাইজড সম্পাদনা পাঠ্যটি ব্যবহার করতে পারেন।
সাইদ মোহাম্মদী

নেতিবাচক সংখ্যাগুলি গ্রহণ করতে আমি এই শ্রেণিটি পরিবর্তন করেছি। কোডটি উত্তর হিসাবে নম্র।
মিশেল ফার্নান্দেস

0

এটি সাইদ মোহাম্মদীর উত্তর মত তবে আমি নেতিবাচক সংখ্যাগুলি গ্রহণ করতে পরিবর্তিত হয়েছি।

  package com.example.liberdade.util
    
    import android.text.Editable
    import android.text.TextWatcher
    import android.widget.EditText
    import java.lang.ref.WeakReference
    import java.math.BigDecimal
    import java.text.NumberFormat
    import java.util.*
    
    
    class MoneyTextWatcher : TextWatcher {
    
    
    
        private val editTextWeakReference: WeakReference<EditText?>?
        private val locale: Locale = Locale("pt", "BR")
        //private final Locale locale;
    
        constructor(editText: EditText?, locale: Locale?) {
            editTextWeakReference = WeakReference<EditText?>(editText)
            //this.locale = if (locale != null) locale else Locale.getDefault()
        }
    
        constructor(editText: EditText?) {
            editTextWeakReference = WeakReference<EditText?>(editText)
            //locale = Locale.getDefault()
        }
    
        override fun beforeTextChanged(
            s: CharSequence?,
            start: Int,
            count: Int,
            after: Int
        ) {
        }
    
        override fun onTextChanged(
            s: CharSequence?,
            start: Int,
            before: Int,
            count: Int
        ) {
        }
    
        override fun afterTextChanged(editable: Editable?) {
            val editText: EditText = editTextWeakReference?.get() ?: return
            editText.removeTextChangedListener(this)
    
            var isNegative = false
            var editableString = editable.toString()
            if (editable != null) {
                if (editableString.contains('-')) {
                    isNegative = true
                    if (editable != null) {
                        editableString = editableString.replace("-","")
                    }
                }
            }
    
            val parsed: BigDecimal? = parseToBigDecimal(editableString, locale)
            //val parsed: BigDecimal? = parseToBigDecimal(editable.toString(), locale)
            var formatted: String = NumberFormat.getCurrencyInstance(locale).format(parsed)
    
            if (isNegative && !(formatted.equals("R\$ 0,00") || formatted.equals("-R\$ 0,00"))) formatted = "-${formatted}"
            editText.setText(formatted)
            editText.setSelection(formatted.length)
            editText.addTextChangedListener(this)
        }
    
        private fun parseToBigDecimal(value: String?, locale: Locale?): BigDecimal? {
            val replaceable = java.lang.String.format(
                "[%s,.\\s]",
                NumberFormat.getCurrencyInstance(locale).currency.symbol
            )
            val cleanString = value!!.replace(replaceable.toRegex(), "")
            return BigDecimal(cleanString).setScale(
                2, BigDecimal.ROUND_FLOOR
            ).divide(
                BigDecimal(100), BigDecimal.ROUND_FLOOR
            )
        }
    }
    
    //como invocar
    //binding.editTextValorCaixa.addTextChangedListener(MoneyTextWatcher(binding.editTextValorCaixa, Locale("pt", "BR")))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.