1

我有用於計算貨幣相關內容的編輯文本視圖。 編輯文本從0.00開始。
這是用於計費的目的,其中供應商輸入要向客戶收取的賬單金額。用戶只能在編輯文本框中輸入0-9的數字。使用RxBinding實現addTextChangedListener以進行基於貨幣的計算

如果用戶輸入1,它成爲0.01
如果用戶輸入2,它成爲0.12等

這是我與被正常使用TextWatcher使用的代碼。

etInitialOtherBill.addTextChangedListener(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) { 
       if(!s.toString().equals(currentO) && !s.toString().equals("")){ 
        etInitialOtherBill.removeTextChangedListener(this); 
        String cleanString = s.toString().replace(".", ""); 
        double parsed = Double.parseDouble(cleanString); 
        String formatted = NumberFormat.getCurrencyInstance().format((parsed/100)); 
        currentO = formatted.replace(NumberFormat.getCurrencyInstance().getCurrency().getSymbol(),""); 
        //new 
        currentO=currentO.replace("\u00A0","").replace(",",""); 
        etInitialOtherBill.setText(currentO); 
        etInitialOtherBill.setSelection(currentO.length()); 
        etInitialOtherBill.addTextChangedListener(this); 
       } 
      } 
      @Override 
      public void afterTextChanged(Editable s) { 
       Double initialMBill, initialOBill; 
       if (etInitialMedicineBill.getText().toString().equals("") || etInitialMedicineBill.getText().toString().equals(".")){ 
        initialMBill=0.00; 
       }else { 
        initialMBill= Double.valueOf(etInitialMedicineBill.getText().toString()); 
       } 
       if (etInitialOtherBill.getText().toString().equals("") || etInitialOtherBill.getText().toString().equals(".")){ 
        initialOBill=0.00; 
       }else { 
        initialOBill= Double.valueOf(etInitialOtherBill.getText().toString()); 
       } 
       Double discountM =Math.round(initialMBill * 100.0 *discountToConsumer)/100.0; 
       Double netMBill = Math.round(initialMBill * 100.0 *amountPayable)/100.0; 
       Double finalBill = netMBill+initialOBill; 
       tvDiscountMedicine.setText(df2.format(discountM)); 
       tvNetMedicineBill.setText(df2.format(netMBill)); 
       tvFinalBill.setText(df2.format(finalBill)); 
      } 
     }); 

afterTextChanged是執行一些計算和TextView

顯示它目前我曾嘗試是

   RxTextView.textChanges(editText) 
       .map(new Func1<CharSequence, CharSequence>() { 
        @Override 
        public CharSequence call(CharSequence charSequence) { 
         //perform calculations as in onTextChanged 
         //This causes the infinite loop. Adding if statements did not solve my problem either 
         return someValue 
        } 
       }) 
       .subscribe(new Action1<CharSequence>() { 
        @Override 
        public void call(CharSequence charSequence) { 
         //If user inputs a number which was formatted, then display it 
         editText.setText(charSequence); 
         editText.setSelection(charSequence.length() 
        } 
       }); 

現在,這臺在一個無限循環的代碼,它可以避免removeTextChangedListener(this)。我試圖使用subscription.unsubscribe(),但這並沒有讓我得到任何地方。

我正在尋找一些指導,我可以再次嘗試。

回答

0

您可以嘗試創建自己的CustomEditText並實現想要的行爲,如下面的代碼。我希望這有助於

public class CustomEditText extends EditText{ 

    List<TextWatcher> textWatchers = new ArrayList<>(); 
    private TextWatcher watcher; 

    public CustomEditText(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void addTextChangedListener(TextWatcher watcher) { 
     textWatchers.add(watcher); 
    } 

    @Override 
    public void setText(CharSequence text, BufferType type) { 
     if (watcher == null) { 
      watcher= new TextWatcher() { 
       @Override 
       public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
        for (TextWatcher watcher : textWatchers) { 
         watcher.beforeTextChanged(s, start, count, after); 
        } 

       } 

       @Override 
       public void onTextChanged(CharSequence s, int start, int before, int count) { 
        for (TextWatcher watcher : textWatchers) { 
         watcher.onTextChanged(s, start, before, count); 
        } 
       } 

       @Override 
       public void afterTextChanged(Editable s) { 
        for (TextWatcher watcher : textWatchers) { 
         watcher.afterTextChanged(s); 
        } 
       } 
      }; 
     } 

     super.removeTextChangedListener(watcher); 
     super.setText(text, type); 
     super.addTextChangedListener(watcher); 
    } 
} 

MainActivity

final CustomEditText editText = (CustomEditText) findViewById(R.id.custom_edit_text); 
    RxTextView.textChanges(editText) 
      .map(new Func1<CharSequence, CharSequence>() { 
       @Override 
       public CharSequence call(CharSequence charSequence) { 
        return charSequence; 
       } 
      }) 
      .subscribe(new Action1<CharSequence>() { 
       @Override 
       public void call(CharSequence charSequence) { 
        Log.d(TAG, "call: Check infinite loop"); 
        editText.setText(charSequence + " " + charSequence.length()); 
        editText.setSelection(charSequence.length()); 
       } 
      }); 
+0

明天我會試試這個,在這裏睡覺的時候。但是,這是一個很大的代碼,讓我想知道使用addTextChangedListener比做這一切更令人頭疼。 –

0

短,但哈克的解決方案。

{ 
    ConnectableObservable<TextViewTextChangeEvent> onTextChanges = 

    RxTextView.textChangeEvents(textView).publish(); 

    onTextChanges 
      .filter(event -> isUser(event.view())) 
      .map(this::changeProps) 
      .subscribe(event -> { 
       textView.setTag(Source.APP); 
       setTextProps(textView, event); 
      }); 

    onTextChanges.filter(event -> isApp(event.view())) 
      .delay(1, TimeUnit.MILLISECONDS).subscribe(event -> { 
     event.view().setTag(Source.USER); 
    }); 

    onTextChanges.connect(); 
} 

private boolean isApp(View view) { 
    return view.getTag() == null || Source.APP.equals(view.getTag()); 
} 

private boolean isUser(View view) { 
    return Source.USER.equals(view.getTag()); 
} 

private static final class Source { 
    public static final String APP = "APP"; 
    public static final String USER = "USER"; 
}