2015-08-11 2 views
0

Я хочу отформатировать номер, когда пользователь вводит номер в поле редактирования.Как форматировать номер с помощью поляchangelistener

Я использую ниже код для форматирования числа как пользователь изменяет фокус на другой элемент управления, используя onfocus() функцию:

public static String formatNumber(double number, int decimals, String digitGrouping){ 
      Formatter f = new Formatter("en"); 
      String rawNumber = f.formatNumber(number, decimals+1); 

      String rawIntString = rawNumber.substring(0, rawNumber.indexOf(".")); //Basically intString without digit grouping 
      StringBuffer intString = new StringBuffer(); 
      StringBuffer decString = new StringBuffer(rawNumber.substring(rawNumber.indexOf(".")+1)); 
      StringBuffer formattedNumber = new StringBuffer(); 
      int workingVal = 0; 
      int newNum = 0; 
      boolean roundNext; 

      //Add digit grouping 
      int grouplen = 0; 
      int firstDigit; 
      if(rawIntString.charAt(0) == '-'){ 
       firstDigit = 1; 
      }else{ 
       firstDigit = 0; 
      } 
      for(int n=rawIntString.length()-1;n>=firstDigit;n--){ 
       intString.insert(0, rawIntString.substring(n, n+1)); 
       grouplen++; 
       if(grouplen == 3 && n>firstDigit){ 
        intString.insert(0, digitGrouping); 
        grouplen = 0; 
       } 
      } 

      //First, check the last digit 
      workingVal = Integer.parseInt(String.valueOf(decString.charAt(decString.length()-1))); 
      if(workingVal>=5){ 
       roundNext = true; 
      }else{ 
       roundNext = false; 
      } 
      //Get the decimal values, round if needed, and add to formatted string buffer 
      for(int n=decString.length()-2;n>=0;n--){ 
       workingVal = Integer.parseInt(String.valueOf(decString.charAt(n))); 
       if(roundNext == true){ 
        newNum = workingVal + 1; 
        if(newNum == 10){ 
         roundNext = true; 
         newNum = 0; 
        }else{ 
         roundNext = false; 
        } 
        formattedNumber.insert(0, newNum); 
       }else{ 
        formattedNumber.insert(0, workingVal); 
       } 
      } 
      //Now get the integer values, round if needed, and add to formatted string buffer 
      formattedNumber.insert(0, "."); 
      for(int n=intString.length()-1;n>=0;n--){ 
       try{ 
        workingVal = Integer.parseInt(String.valueOf(intString.charAt(n))); 
       }catch(Exception e){ 
        formattedNumber.insert(0, intString.charAt(n)); 
        continue; 
       } 
       if(roundNext == true){ 
        newNum = workingVal + 1; 
        if(newNum == 10){ 
         roundNext = true; 
         newNum = 0; 
        }else{ 
         roundNext = false; 
        } 
        formattedNumber.insert(0, newNum); 
       }else{ 
        formattedNumber.insert(0, workingVal); 
       } 
      } 

      //Just in case its a number like 9999.99999 (if it rounds right to the end 
      if(roundNext == true){ 
       formattedNumber.insert(0, 1); 

      } 

      //re-add the minus sign if needed 
      if(firstDigit == 1) formattedNumber.insert(0, rawIntString.charAt(0)); 

      if(digitGrouping.length() > 0){ 
       if(formattedNumber.toString().indexOf(".") == -1){ 
        //no decimal 
        if(formattedNumber.toString().indexOf(digitGrouping) > 3+firstDigit){ 
         formattedNumber.insert(1+firstDigit, digitGrouping); 
        } 

        if(formattedNumber.toString().length() == 4+firstDigit){ 
         formattedNumber.insert(1+firstDigit, digitGrouping); 
        } 
       }else{ 
        //no decimal 
        if(formattedNumber.toString().indexOf(digitGrouping) > 3+firstDigit){ 
         formattedNumber.insert(1+firstDigit, digitGrouping); 
        } 

        String intportion = formattedNumber.toString().substring(0, formattedNumber.toString().indexOf(".")); 
        if(intportion.length() == 4+firstDigit){ 
         formattedNumber.insert(1+firstDigit, digitGrouping); 
        } 
       } 
      } 

      //now remove trailing zeros 
      String tmp = formattedNumber.toString(); 
      int newLength = tmp.length(); 
      for(int n=tmp.length()-1;n>=0;n--){ 
       if(tmp.substring(n, n+1).equalsIgnoreCase("0")){ 
        newLength--; 
       }else{ 
        if(tmp.substring(n, n+1).equalsIgnoreCase(".")) newLength--; 
        break; 
       } 
      } 
      formattedNumber.setLength(newLength); 

      return formattedNumber.toString(); 
     } 

Это не решает проблему форматирования числа как типов пользователей, хоть.

+0

Является ли проблема, потому что функция не возвращает требуемое значение или потому, что она не вызвана фокусом? или он называется правильно, но все же значение поля не изменяется? Кроме того, какой тип виджета вы используете? –

+0

@Arye Shemesh Я хочу, чтобы число было отформатировано как номер пользователя, вводимого одновременно в editfield.Now я использую onfocus, так что если у меня есть два поля редактирования в фокусе для второго номера поля редактирования в первом editfied, отформатируйте его, но я не хочу, чтобы мое приложение работаю так, поэтому я хочу сделать число, отформатированное как номер пользователя в поле редактирования. – allDroid

+0

Похоже, вы должны добавить его в качестве прослушивателя изменений. Фокус происходит только один раз, прежде чем пользователь начнет печатать. –

ответ

0

Очевидным решением для меня является переопределение метода рисования EditField, чтобы он отображался как форматированный текст. Поле getText поля вернет «12345», пока оно будет отображаться как «12 345», например.

Это почти идеально подходит для вас. Но вы также должны помнить, как рисовать курсор. Вы не хотите, нативный курсор на 5, но опираясь на 3.

EDIT

Это должно помочь вам. Важными частями здесь являются paint и getFocusRect. Обратите внимание, что это довольно грубо. Он не обрабатывает события касания (курсор не будет двигаться правильно), и не будет обертывания строки (должно обрабатываться layout и paint способами).

public class FormattedEditField extends TextField 
{ 
    public FormattedEditField() 
    { 
     setFilter(TextFilter.get(TextFilter.NUMERIC)); 
    } 

    protected String getFormattedText() 
    { 
     String text = getText(); 
     if ((text == null) || (text.length() == 0)) 
     { 
      return ""; 
     } 
     else 
     { 
      double nr = Double.parseDouble(text); 
      return formatNumber(nr, 2, ","); 
     } 
    } 

    public synchronized void getFocusRect(XYRect rect) 
    { 
     // Tell Blackberry where to draw the cursor 
     Font font = getFont(); 
     String formattedText = getFormattedText(); 
     int length = formattedText.length(); 

     if (length == 0) 
     { 
      rect.x = getTextOriginX(); 
      rect.width = font.getAdvance('1'); 
      rect.y = getTextOriginY(); 
      rect.height = font.getHeight(); 
     } 
     else 
     { 
      int cursorPosition = getCursorPosition(); 

      int i; 
      for (i = 0; i <= cursorPosition; i++) 
      { 
       if (cursorPosition == length) 
       { 
        break; 
       } 

       if (formattedText.charAt(i) == ',') 
       { 
        cursorPosition++; 
       } 
      } 

      if (cursorPosition >= length) 
      { 
       rect.x = getTextOriginX() + font.getAdvance(formattedText); 
       rect.width = font.getAdvance('1'); 
      } 
      else 
      { 
       rect.x = getTextOriginX() + font.getAdvance(formattedText.substring(0, cursorPosition)); 
       rect.width = font.getAdvance(formattedText.charAt(cursorPosition)); 
      } 

      rect.y = getTextOriginY(); 
      rect.height = font.getHeight(); 
     } 
    } 

    protected void drawFocus(Graphics graphics, boolean on) 
    { 
    } 

    protected synchronized void paint(Graphics graphics) 
    { 
     int x = getTextOriginX(); 
     int y = getTextOriginY(); 

     String text = getFormattedText(); 

     if (isFocus()) 
     { 
      XYRect rect = new XYRect(); 
      getFocusRect(rect); 

      int colour = graphics.getColor(); 
      graphics.setColor(0x207CFE); 
      graphics.fillRect(rect.x, rect.y, rect.width, rect.height); 
      graphics.setColor(colour); 

      graphics.drawText(text, x, y); 
      graphics.invert(rect); 
     } 
     else 
     { 
      graphics.drawText(text, x, y); 
     } 
    } 

    // Since we are overriding the painting, we should accommodate the different drawing flags 
    private int getTextOriginX() 
    { 
     int x = 0; 

     if ((getStyle() & DrawStyle.HCENTER) == DrawStyle.HCENTER) 
     { 
      x = (getWidth() - getFont().getAdvance(getFormattedText()))/2; 
     } 
     else if ((getStyle() & DrawStyle.RIGHT) == DrawStyle.RIGHT) 
     { 
      x = getWidth() - getFont().getAdvance(getFormattedText()); 
     } 

     return x; 
    } 

    // Since we are overriding the painting, we should accommodate the different drawing flags 
    private int getTextOriginY() 
    { 
     int y = 0; 
     if ((getStyle() & DrawStyle.VCENTER) == DrawStyle.VCENTER) 
     { 
      y = (getHeight() - getFont().getHeight())/2; 
     } 
     else if ((getStyle() & DrawStyle.BOTTOM) == DrawStyle.BOTTOM) 
     { 
      y = getHeight() - getFont().getHeight(); 
     } 

     return y; 
    } 

    // This method is from http://supportforums.blackberry.com/t5/Java-Development/Format-a-decimal-number/m-p/763981#M142257 
    // I don't know how good it is, since I use my own method for this 
    private String formatNumber(double number, int decimals, String digitGrouping) 
    { 
     Formatter f = new Formatter("en"); 
     String rawNumber = f.formatNumber(number, decimals + 1); 

     String rawIntString = rawNumber.substring(0, rawNumber.indexOf(".")); // Basically intString without digit grouping 
     StringBuffer intString = new StringBuffer(); 
     StringBuffer decString = new StringBuffer(rawNumber.substring(rawNumber.indexOf(".") + 1)); 
     StringBuffer formattedNumber = new StringBuffer(); 
     int workingVal = 0; 
     int newNum = 0; 
     boolean roundNext; 

     // Add digit grouping 
     int grouplen = 0; 
     int firstDigit; 
     if (rawIntString.charAt(0) == '-') 
     { 
      firstDigit = 1; 
     } 
     else 
     { 
      firstDigit = 0; 
     } 
     for (int n = rawIntString.length() - 1; n >= firstDigit; n--) 
     { 
      intString.insert(0, rawIntString.substring(n, n + 1)); 
      grouplen++; 
      if (grouplen == 3 && n > firstDigit) 
      { 
       intString.insert(0, digitGrouping); 
       grouplen = 0; 
      } 
     } 

     // First, check the last digit 
     workingVal = Integer.parseInt(String.valueOf(decString.charAt(decString.length() - 1))); 
     if (workingVal >= 5) 
     { 
      roundNext = true; 
     } 
     else 
     { 
      roundNext = false; 
     } 
     // Get the decimal values, round if needed, and add to formatted string buffer 
     for (int n = decString.length() - 2; n >= 0; n--) 
     { 
      workingVal = Integer.parseInt(String.valueOf(decString.charAt(n))); 
      if (roundNext == true) 
      { 
       newNum = workingVal + 1; 
       if (newNum == 10) 
       { 
        roundNext = true; 
        newNum = 0; 
       } 
       else 
       { 
        roundNext = false; 
       } 
       formattedNumber.insert(0, newNum); 
      } 
      else 
      { 
       formattedNumber.insert(0, workingVal); 
      } 
     } 
     // Now get the integer values, round if needed, and add to formatted string buffer 
     formattedNumber.insert(0, "."); 
     for (int n = intString.length() - 1; n >= 0; n--) 
     { 
      try 
      { 
       workingVal = Integer.parseInt(String.valueOf(intString.charAt(n))); 
      } 
      catch (Exception e) 
      { 
       formattedNumber.insert(0, intString.charAt(n)); 
       continue; 
      } 
      if (roundNext == true) 
      { 
       newNum = workingVal + 1; 
       if (newNum == 10) 
       { 
        roundNext = true; 
        newNum = 0; 
       } 
       else 
       { 
        roundNext = false; 
       } 
       formattedNumber.insert(0, newNum); 
      } 
      else 
      { 
       formattedNumber.insert(0, workingVal); 
      } 
     } 

     // Just in case its a number like 9999.99999 (if it rounds right to the end 
     if (roundNext == true) 
     { 
      formattedNumber.insert(0, 1); 
     } 

     // re-add the minus sign if needed 
     if (firstDigit == 1) 
      formattedNumber.insert(0, rawIntString.charAt(0)); 

     if (digitGrouping.length() > 0) 
     { 
      if (formattedNumber.toString().indexOf(".") == -1) 
      { 
       // no decimal 
       if (formattedNumber.toString().indexOf(digitGrouping) > 3 + firstDigit) 
       { 
        formattedNumber.insert(1 + firstDigit, digitGrouping); 
       } 

       if (formattedNumber.toString().length() == 4 + firstDigit) 
       { 
        formattedNumber.insert(1 + firstDigit, digitGrouping); 
       } 
      } 
      else 
      { 
       // no decimal 
       if (formattedNumber.toString().indexOf(digitGrouping) > 3 + firstDigit) 
       { 
        formattedNumber.insert(1 + firstDigit, digitGrouping); 
       } 

       String intportion = formattedNumber.toString().substring(0, formattedNumber.toString().indexOf(".")); 
       if (intportion.length() == 4 + firstDigit) 
       { 
        formattedNumber.insert(1 + firstDigit, digitGrouping); 
       } 
      } 
     } 

     // now remove trailing zeros 
     String tmp = formattedNumber.toString(); 
     int newLength = tmp.length(); 
     for (int n = tmp.length() - 1; n >= 0; n--) 
     { 
      if (tmp.substring(n, n + 1).equalsIgnoreCase("0")) 
      { 
       newLength--; 
      } 
      else 
      { 
       if (tmp.substring(n, n + 1).equalsIgnoreCase(".")) 
        newLength--; 
       break; 
      } 
     } 
     formattedNumber.setLength(newLength); 

     return formattedNumber.toString(); 
    } 
} 
+0

Не могли бы вы показать мне пример.если я ввожу номер ex: 2345456, он должен отображаться как 2,345,456.00, тогда должна быть точка децима и два нуля после этой десятичной точки. Эти форматирование должно происходить как пользовательские типы в editfield.Cant я использую Fieldchangelistener? если да, то как? – allDroid

+0

Добавлен пример реализации, по-прежнему вам понадобится какая-то работа, хотя – Kevin

+0

это прекрасно работает, но после 17 цифр его округлить, как и в коде, я пытался модифицировать и удалять функцию codeor, которая делает округление числа, но когда я это делаю, я не в состоянии ввести что-либо в текстовое поле, где я ошибаюсь? – allDroid

Смежные вопросы