【问题标题】:App crashes when "=" button is pressed when getText is empty - Android Studio当getText为空时按下“=”按钮时应用程序崩溃 - Android Studio
【发布时间】:2018-09-07 21:30:18
【问题描述】:

我有一个计算器应用程序在按下等号按钮时崩溃,并且 EditText 中没有任何东西可以从中获取文本。我已经查看了其他类似情况的问题,但这些建议不起作用。我是 android 新手,需要任何帮助。如果我的 EditText.setText() 中有一个“0”,我也会遇到问题,当它们被按下时,“0”会停留在其他数字的前面。如果您需要更多代码来帮助,请告诉我。

这里是 Logcat 信息

09-08 07:58:32.915 13726-13726/com.ruthadeaton.bld3.calculator
E/AndroidRuntime: 致命异常: main 进程:com.ruthadeaton.bld3.calculator,PID:13726 java.lang.NumberFormatException: 空字符串
atsun.misc.FloatingDecimal.readJavaFormatString (FloatingDecimal.java:1842) 在 sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122) 在 java.lang.Float.parseFloat(Float.java:451) 在 com.ruthadeaton.bld3.calculator.MainActivity$26.onClick (MainActivity.java:346) 在 android.view.View.performClick(View.java:6597) 在 android.view.View.performClickInternal(View.java:6574) 在 android.view.View.access$3100(View.java:778) 在 android.view.View$PerformClick.run(View.java:25885) 在 android.os.Handler.handleCallback(Handler.java:873) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:193) 在 android.app.ActivityThread.main(ActivityThread.java:6669) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

这是我的代码:

buttonEqual.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mValueTwo=Float.parseFloat(edt1.getText() + "");
            if (mAddition == true) {
                edt1.setText(mValueOne + mValueTwo + "");
                mAddition=false;
            }
            if (mSubtract == true) {
                edt1.setText(mValueOne - mValueTwo + "");
                mSubtract=false;
            }

            if (mMultiplication == true) {
               edt1.setText(mValueOne * mValueTwo + "");
               mMultiplication=false;
            }

            if (mDivision == true) {
                edt1.setText(mValueOne / mValueTwo + "");
                mDivision=false;
            }
        }
    });

button0.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        edt1.setText(edt1.getText() + "0");
    }
});

buttonAdd.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
        mValueOne=Float.parseFloat(edt1.getText() + "");
        mAddition=true;
        edt1.setText(null);
    }
});

buttonSub.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mValueOne=Float.parseFloat(edt1.getText() + "");
        mSubtract=true;
        edt1.setText(null);
    }
});

buttonMul.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mValueOne=Float.parseFloat(edt1.getText() + "");
        mMultiplication=true;
        edt1.setText(null);
    }
});

buttonDivision.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mValueOne=Float.parseFloat(edt1.getText() + "");
        mDivision=true;
        edt1.setText(null);
     }
});

【问题讨论】:

    标签: android


    【解决方案1】:

    我有一个计算器应用程序在按下等号按钮时崩溃 并且 EditText 中没有任何内容可以从中获取文本。

    因为您不验证来自用户的输入是否有效。显然,空字符串不是导致应用程序以NumberFormatExecption 崩溃的数字。

    如果我的 EditText.setText() 中有“0”,我也会遇到问题, 按下时,“0”会停留在其他数字的前面。

    您可以使用TextWatcher 根据用户输入更新文本视图。

    我将逐步指导您如何解决这些问题

    首先,定义一个方法来验证用户输入是否为有效数字。

    private boolean isValidNumber(String numberInString) {
        try {
            Float.parseFloat(numberInString);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
    

    其次,每次用户按下算术运算符(+、-、*、/)或等于 (=) 时,应用程序都会从​​ edt1 中获取值。然后编写一个方法来避免重复代码。

    /**
     * Get current input from user and try parse it to a number.
     *
     * @return a number if input is valid, otherwise return null.
     */
    private Float getInputValue() {
        Float possibleNumber = null;
        String numberInString = edt1.getText().toString();
        if (isValidNumber(numberInString)) {
            possibleNumber = Float.parseFloat(numberInString);
        }
        return possibleNumber;
    }
    

    第三,防止用户使用TextWatcher添加多个零数。

    edt1.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) {
            String content = s.toString();
            if (content.startsWith("0") && content.length() == 2 && Character.isDigit(content.charAt(1))) {
                edt1.setText(String.valueOf(content.charAt(1)));
                edt1.setSelection(1);
            }
        }
    });
    

    终于把它放在一起了。

    public class MainActivity extends AppCompatActivity {
    
        // Your variables here
        ...
    
        // Make these two variables is Float instead of float.
        Float mValueOne;
        Float mValueTwo;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Your init view here
            ...
    
            edt1.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) {
                    String content = s.toString();
                    if (content.startsWith("0") && content.length() == 2 && Character.isDigit(content.charAt(1))) {
                        edt1.setText(String.valueOf(content.charAt(1)));
                        edt1.setSelection(1);
                    }
                }
            });
    
            buttonEqual.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mValueTwo = getInputValue();
                    if (mValueOne == null || mValueTwo == null) {
                        // One of there or both of two values are not valid then do nothing.
                        return;
                    }
    
                    if (mAddition) {
                        edt1.setText(String.valueOf(mValueOne + mValueTwo));
                        mAddition = false;
                    }
    
                    if (mSubtract) {
                        edt1.setText(String.valueOf(mValueOne + mValueTwo));
                        mSubtract = false;
                    }
    
                    if (mMultiplication) {
                        edt1.setText(String.valueOf(mValueOne + mValueTwo));
                        mMultiplication = false;
                    }
    
                    if (mDivision) {
                        edt1.setText(String.valueOf(mValueOne + mValueTwo));
                        mDivision = false;
                    }
                }
            });
    
            button0.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    edt1.setText(String.valueOf(edt1.getText().toString() + "0"));
                    edt1.setSelection(edt1.getText().length());
                }
            });
    
            buttonAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mValueOne = getInputValue();
                    mAddition = true;
                    edt1.setText(null);
                }
            });
    
            buttonSub.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mValueOne = getInputValue();
                    mSubtract = true;
                    edt1.setText(null);
                }
            });
    
            buttonMul.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mValueOne = getInputValue();
                    mMultiplication = true;
                    edt1.setText(null);
                }
            });
    
            buttonDivision.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mValueOne = getInputValue();
                    mDivision = true;
                    edt1.setText(null);
                }
            });
        }
    
        /**
         * Get current input from user and try parse it to a number.
         *
         * @return a number if input is valid, otherwise return null.
         */
        private Float getInputValue() {
            Float possibleNumber = null;
            String numberInString = edt1.getText().toString();
            if (isValidNumber(numberInString)) {
                possibleNumber = Float.parseFloat(numberInString);
            }
            return possibleNumber;
        }
    
        private boolean isValidNumber(String numberInString) {
            try {
                Float.parseFloat(numberInString);
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      它做不到

      mValueTwo=Float.parseFloat(edt1.getText() + "");
      

      如果 edt1.getText() 为空。 您可以使用 try-catch 更正此问题。

      buttonEqual.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  try{
                      mValueTwo=Float.parseFloat(edt1.getText() + "");
      
                      if (mAddition == true) {
      
                          edt1.setText(mValueOne + mValueTwo + "");
                          mAddition=false;
                      }
      
                      if (mSubtract == true) {
                          edt1.setText(mValueOne - mValueTwo + "");
                          mSubtract=false;
                      }
      
                      if (mMultiplication == true) {
                          edt1.setText(mValueOne * mValueTwo + "");
                          mMultiplication=false;
                      }
      
                      if (mDivision == true) {
                          edt1.setText(mValueOne / mValueTwo + "");
                          mDivision=false;
                      }
                  }catch(Exception e){
                      //eventually logging here
                  } 
              }
         });
      

      否则,您可以在执行 parseFloat 之前进行一些控制

      buttonEqual.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                  String edt = edt1.getText().toString();
                  if(edt.matches("")){
                      //something like a toast to signal
                  }else{
                         mValueTwo=Float.parseFloat(edt1.getText() + "");
      
                          if (mAddition == true) {
      
                              edt1.setText(mValueOne + mValueTwo + "");
                              mAddition=false;
                          }
      
                          if (mSubtract == true) {
                              edt1.setText(mValueOne - mValueTwo + "");
                              mSubtract=false;
                          }
      
                          if (mMultiplication == true) {
                              edt1.setText(mValueOne * mValueTwo + "");
                              mMultiplication=false;
                          }
      
                          if (mDivision == true) {
                              edt1.setText(mValueOne / mValueTwo + "");
                              mDivision=false;
                          }
                      }
                  }
             });
      

      【讨论】:

      • 感谢您的建议。 try-catch 不起作用。
      • 我在最后添加了一个 if (edt1.getText() == null) { 和一个 else 并返回; - 应用程序不崩溃但操作不起作用。
      • try-catch 不起作用真的很奇怪。我想我记性不好,你应该在 catch 里面写“Exception e”而不是“Error e”。否则,在您的最新版本中,我希望您将所有实际代码放在“else”中
      • 无论如何你应该将edittext转换为字符串。然后你可以检查字符串是否为 ==""。这里: edt = edt1.getText().toString(); if (edt.matches("")) { //无事可做 }else{ //yourcodehere }
      • 啊!异常解决了它的问题。我也应该抓住它。
      【解决方案3】:

      您可以在编辑文本中设置提示属性,以便在实际插入数字时它会消失。

      android:hint="0"
      

      对于前面的 0,也许你希望你的编辑文本是数字格式

      android:inputType = "numberDecimal"
      

      您没有粘贴崩溃的堆栈跟踪,但我会假设它是空指针异常

      if (edt1.getText != null) { /* do whatever executions */}
      

      【讨论】:

      • 感谢您的建议。我之前尝试过提示,但没有运气。我的 inputType 是 numberDecimal 和 numberPassword 只是在屏幕上放点。我在找数字。我将很快添加堆栈跟踪。再次感谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      相关资源
      最近更新 更多