2017-05-12 36 views
1

저는 서로 통신하려고하는 내 Android app에 3 개의 EditText 필드가 있습니다. 주문 총계, 수령액 및 팁입니다. 사용자는 첫 번째 EditText에 주문 가격을 입력합니다. 다른 두 EditText는 각각의 값에 따라 수정하고 싶은 EditText입니다. 사용자가 총 주문에서 20.00을 받고받은 금액에서 25.00을 입력하면 팁에 5.00이 표시됩니다. 마찬가지로 주문 총계에 20.00을 입력하고 팁에 5.00을 입력하면 수취 한 금액을 25.00으로 표시하고 싶습니다. 모든 계산이 정확하고 다른 하나는 주석으로 처리하는 한 TextWatcher의 각 작업이 작동하지만 두 작업 모두 무한 루프가 생성됩니다. 이 작업을 수행 할 수있는 좋은 방법이 있습니까? 아니면 누군가가 도움이되는 링크의 올바른 방향을 가르쳐 줄 수 있습니까? 나는 내가하려고하는 일을 찾지 못한다. eTip 하나 하나에 :두 명의 TextWatchers가 무한 루프를 만듭니다.

당신은 2 textWatchers이 : 무슨 당신이 afterTextChanged 콜백

withing에에서의 setText 방법을 반복하는

eTotalCost = (EditText) findViewById(R.id.orderTotal); 
eAmountReceived = (EditText) findViewById(R.id.amountReceived); 
eTip = (EditText) findViewById(R.id.tip); 
eMileage = (EditText) findViewById(R.id.mileage); 
eGrandTotal = (EditText) findViewById(R.id.grandTotal); 

eAmountReceived.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){} 

    @Override 
    public void afterTextChanged(Editable s) 
    { 
     eAmountReceived = (EditText) findViewById(R.id.amountReceived); 
     eTotalCost = (EditText) findViewById(R.id.orderTotal); 
     eTip = (EditText) findViewById(R.id.tip); 
     eMileage = (EditText) findViewById(R.id.mileage); 
     eGrandTotal = (EditText) findViewById(R.id.grandTotal); 

     sAmountReceived = eAmountReceived.getText().toString(); 
     sTotalCost = eTotalCost.getText().toString(); 
     sMileage = eMileage.getText().toString(); 
     sTip = eTip.getText().toString(); 

     try 
     { 
      dAmountReceived = Double.parseDouble(sAmountReceived); 
      dTotalCost = Double.parseDouble(sTotalCost); 

      dSubtract = dAmountReceived - dTotalCost; 
      dMileage = Double.parseDouble(sMileage); 
      dGrandTotal = dSubtract + dMileage; 
     } catch(NumberFormatException e){} 

     sTip = String.valueOf(dSubtract); 

     DecimalFormat df = new DecimalFormat("0.00"); 
     sTip = df.format(dSubtract); 

     eTip.setText(sTip); 

     sGrandTotal = String.valueOf(dGrandTotal); 
     sGrandTotal = df.format(dGrandTotal); 
     eGrandTotal.setText(sGrandTotal); 
    } 
}); 


eTip.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){} 

    @Override 
    public void afterTextChanged(Editable s) { 
     eAmountReceived = (EditText) findViewById(R.id.amountReceived); 
     eTotalCost = (EditText) findViewById(R.id.orderTotal); 
     eTip = (EditText) findViewById(R.id.tip); 
     eMileage = (EditText) findViewById(R.id.mileage); 
     eGrandTotal = (EditText) findViewById(R.id.grandTotal); 

     sAmountReceived = eAmountReceived.getText().toString(); 
     sTotalCost = eTotalCost.getText().toString(); 
     sMileage = eMileage.getText().toString(); 
     sTip = eTip.getText().toString(); 

     try 
     { 
      dTip = Double.parseDouble(sTip); 
      dTotalCost = Double.parseDouble(sTotalCost); 

      dAdd = dTotalCost + dTip; 
      dMileage = Double.parseDouble(sMileage); 
      dGrandTotal = dTip + dMileage; 
     } catch (NumberFormatException e) {} 

     sAmountReceived = String.valueOf(dAdd); 

     DecimalFormat df = new DecimalFormat("0.00"); 
     sAmountReceived = df.format(dAdd); 

     eAmountReceived.setText(sAmountReceived); 

     sGrandTotal = String.valueOf(dGrandTotal); 
     sGrandTotal = df.format(dGrandTotal); 
     eGrandTotal.setText(sGrandTotal); 
    } 
}); 

답변

2

을 다음과 같이

내 코드입니다 eAmountReceived

필드 중 하나에 setText()을 호출하면 루핑이 시작되고, 의 setText가 afterTextChanged을 트리거하고 텍스트의 모두 당신이하는 다시,이를 방지하기 위해 afterTextChanged

를 트리거 반대 필드 setText()를 호출 당직자 때문에, 값이 이미 각각 글고 설정되어 표시됩니다 일부 부울 플래그를 소개합니다 새로운 값이 이미 설정된 이전 값과 다른 경우에만 setText를 호출하십시오.

+0

아직 부울 플래그에 익숙하지 않습니다. 나는 isSet() 함수를 만들었고 나는 그것과 함께 올바른 방향에 있다고 생각했지만 그렇지 않다고 생각한다. 그러나, 각 afterTextChanged에서 if (getCurrentFocus() == myEditText)를 수행하여 작동하도록했습니다. – deadAhead

1

먼저, afterTextChanged에서 findviewbyid 코드를 삭제하십시오. 모든 용도로 선언 할 필요는 없습니다. onCreate에서만 사용할 수 있습니다.

질문에 대한 가장 쉬운 해결책은 클래스에 선언 된 변수에 TextWatchers를 유지하는 것입니다. 그런 다음 모든 setText() 호출 전에 모든 textWatchers에 대해 removeTextChangeListener를 호출하고 setText() 후에 textWatchers를 다시 추가하십시오.

편집 : 모든 setText() 호출을 제거하고 다시 추가하지 않습니다. 조건을 만들 때에 만 루프를 만듭니다.

0

환율 계산기 앱을 만들 때 이와 똑같은 문제가 발생했습니다. (editText 1의 값을 변경하면 editText 2의 값이 변경되고 그 반대의 경우도 마찬가지입니다.)

나는 두 명의 텍스트 전문가를 생성하는 방법을 사용했습니다.

private TextWatcher TextWatcherClass = new TextWatcher() { 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, 
           int count) { 
     editText2.removeTextChangedListener(TextWatcherClass2); 

     } 

    } 

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

    @Override 
    public void afterTextChanged(Editable s) { 

     editText2.addTextChangedListener(TextWatcherClass2); 
    } 

}; 

private TextWatcher TextWatcherClass2 = new TextWatcher() { 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, 
           int count) { 
     editText1.removeTextChangedListener(TextWatcherClass); 
     } 
    } 

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

    @Override 
    public void afterTextChanged(Editable s) { 

     editText1.addTextChangedListener(TextWatcherClass); 
    } 

}; 

희망이 있습니다.