2017-06-08 6 views
0

私はの次のパターンを持っています"#,###.###" しかし、50.05のように入力したいときは、文字列を解析してテキストが変わる度に私はそれが私が50.05のように数字を入力できるようにするには何ができるかを任意のアイデアを50.を返し、0DecimalFormat Javaがドットの後に0を入力できるようにする

をカット

df.parse("50.0"); 

を呼びますか?

私のクラスの完全なコードを以下に示します。申し訳ありませんが、それはあまりにも冗長である場合:

private class NumberTextWatcher implements TextWatcher { 
    @SuppressWarnings("unused") 
    private static final String TAG = "NumberTextWatcher"; 

    private DecimalFormat df; 
    private DecimalFormat dfnd; 
    private boolean hasFractionalPart; 

    private EditText et; 

    NumberTextWatcher(EditText et) { 
     df = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH); 
     df.applyLocalizedPattern(hasThousandSeparator ? "#,###.###" : "####.###"); 
     df.setDecimalSeparatorAlwaysShown(true); 
     df.setMaximumFractionDigits(maxDecimal); 
     dfnd = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH); 
     dfnd.applyLocalizedPattern(hasThousandSeparator ? "#,###" : "####"); 
     dfnd.setMaximumFractionDigits(maxDecimal); 
     this.et = et; 
     hasFractionalPart = false; 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     et.removeTextChangedListener(this); 

     try { 
      int inilen, endlen; 
      inilen = et.getText().length(); 

      String sign = hasSign ? s.toString().startsWith("-") ? "-" : "+" : null; 
      String sStr = hasSignAttached(s) ? s.toString().substring(1) : s.toString(); 

      String v = sStr.replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), ""); 

      if(v.length() == 0){ 
       return; 
      } 

      if(hasFractionalPart){ 
       String[] vSplit = v.split("\\."); 

       String intStr = vSplit[0]; 
       String decStr = vSplit.length > 1 ? vSplit[1] : ""; 

       if(intStr.length() > maxNumbers) 
        intStr = intStr.substring(0, maxNumbers); 

       if(decStr.length() > maxDecimal) 
        decStr = decStr.substring(0, maxDecimal); 

       v = String.format("%s.%s", intStr, decStr); 
      } else { 
       if(v.length() > maxNumbers) 
        v = v.substring(0, maxNumbers); 
      } 


      Number n = df.parse(v); 
      int cp = et.getSelectionStart(); 

      String formatted; 

      if (hasFractionalPart) { 
       formatted = df.format(n); 
      } else { 
       formatted = dfnd.format(n); 
      } 

      et.setText(hasSign ? String.format("%s%s", sign, formatted) : formatted); 

      endlen = et.getText().length(); 
      int sel = (cp + (endlen - inilen)); 
      if (sel > 0 && sel <= et.getText().length()) { 
       et.setSelection(sel); 
      } else { 
       // place cursor at the end? 
       et.setSelection(et.getText().length() - 1); 
      } 

     } catch (Exception e) { 
      ExceptionTracker.trackException(e); 
     } finally { 
      et.addTextChangedListener(this); 
     } 
    } 

    private boolean hasSignAttached(Editable s){ 
     return s.toString().startsWith("+") || s.toString().startsWith("-"); 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     if(hasSign && start == 1 && count == 1){ 
      et.setText(""); 
     } 
    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     hasFractionalPart = s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())); 
    } 
} 

答えて

1

このコードは、問題解決:

import java.text.DecimalFormat; 

public class DecimalFormatExample { 

    public static void main(String[] args) { 

    DecimalFormat dformat = new DecimalFormat("#,###.###"); 
    dformat.setMinimumFractionDigits(1); 

    String someNumber = "50.05"; 
    Double someNumberDouble = Double.valueOf(someNumber); 
    System.out.println(dformat.format(someNumberDouble)); // 50.05 

    someNumber = "50.0"; 
    someNumberDouble = Double.valueOf(someNumber); 
    System.out.println(dformat.format(someNumberDouble)); // 50.0 

    } 
} 
+0

問題は "50.0" は "50" になることです0は失われます。だから私はこれをonTextChangeで行うときには入力できません50.05 – Andranik

+0

後続のゼロを保持する方法を示すコードを編集しました –

0

[OK]を、私はこの問題を解決するために、小さなハックを行っています。将来誰かを助けるか、誰かがより良い解決策を提案するかもしれません。

だから私は、以下のチェックを追加しました:

boolean decHasZeroAtEnd = false; 
....... 
if(decStr.endsWith("0")){ 
     decHasZeroAtEnd = true; 
} 
....... 
if(decHasZeroAtEnd){ 
    decHasZeroAtEnd = false; 
    formatted = String.format("%s0", formatted); 
} 

、全体のコードは以下の通りです:

private class NumberTextWatcher implements TextWatcher { 
    @SuppressWarnings("unused") 
    private static final String TAG = "NumberTextWatcher"; 

    private DecimalFormat df; 
    private DecimalFormat dfnd; 
    private boolean hasFractionalPart; 

    private EditText et; 

    NumberTextWatcher(EditText et) { 
     df = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH); 
     df.applyLocalizedPattern(hasThousandSeparator ? "#,###.###" : "####.###"); 
     df.setDecimalSeparatorAlwaysShown(true); 
     df.setMaximumFractionDigits(maxDecimal); 
     dfnd = (DecimalFormat) DecimalFormat.getInstance(Locale.ENGLISH); 
     dfnd.applyLocalizedPattern(hasThousandSeparator ? "#,###" : "####"); 
     dfnd.setMaximumFractionDigits(maxDecimal); 
     this.et = et; 
     hasFractionalPart = false; 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     et.removeTextChangedListener(this); 

     try { 
      int inilen, endlen; 
      inilen = et.getText().length(); 

      String sign = hasSign ? s.toString().startsWith("-") ? "-" : "+" : null; 
      String sStr = hasSignAttached(s) ? s.toString().substring(1) : s.toString(); 

      String v = sStr.replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), ""); 

      if(v.length() == 0){ 
       return; 
      } 

      boolean decHasZeroAtEnd = false; 

      if(hasFractionalPart){ 
       String[] vSplit = v.split("\\."); 

       String intStr = vSplit[0]; 
       String decStr = vSplit.length > 1 ? vSplit[1] : ""; 

       if(intStr.length() > maxNumbers) 
        intStr = intStr.substring(0, maxNumbers); 

       if(decStr.length() > maxDecimal) 
        decStr = decStr.substring(0, maxDecimal); 


       if(decStr.endsWith("0")){ 
        decHasZeroAtEnd = true; 
       } 

       v = String.format("%s.%s", intStr, decStr); 
      } else { 
       if(v.length() > maxNumbers) 
        v = v.substring(0, maxNumbers); 
      } 

      Number n = df.parse(v); 
      int cp = et.getSelectionStart(); 

      String formatted; 

      if (hasFractionalPart) { 
       formatted = df.format(n); 
      } else { 
       formatted = dfnd.format(n); 
      } 

      if(decHasZeroAtEnd){ 
       decHasZeroAtEnd = false; 
       formatted = String.format("%s0", formatted); 
      } 

      Log.d("testt", "formatted " + formatted); 

      et.setText(hasSign ? String.format("%s%s", sign, formatted) : formatted); 

      endlen = et.getText().length(); 
      int sel = (cp + (endlen - inilen)); 
      if (sel > 0 && sel <= et.getText().length()) { 
       et.setSelection(sel); 
      } else { 
       // place cursor at the end? 
       et.setSelection(et.getText().length() - 1); 
      } 

     } catch (Exception e) { 
      ExceptionTracker.trackException(e); 
     } finally { 
      et.addTextChangedListener(this); 
     } 
    } 

    private boolean hasSignAttached(Editable s){ 
     return s.toString().startsWith("+") || s.toString().startsWith("-"); 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     if(hasSign && start == 1 && count == 1){ 
      et.setText(""); 
     } 
    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     hasFractionalPart = s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())); 
    } 
} 
関連する問題