0

此代码创建一个搜索栏,并使搜索栏创建与滑块所在的一样多的 EditText 字段/删除那些太多的字段。此代码在 OnActivityCreated

final LinearLayout linearLayout = (LinearLayout) getActivity()
  .findViewById(R.id.npv_calcfields);
EditText editText = new EditText(getActivity());
editText.setId(i);
editText.setLayoutParams(new LayoutParams(
  LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
  SeekBar bar = (SeekBar) getActivity().findViewById(R.id.npv_seekbar);
  final TextView selection = (TextView) getActivity()
    .findViewById(R.id.npv_selected);
  bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
    public void onProgressChanged(SeekBar seekbar, int progress,
      boolean fromUser) {
      selection.setText("You have selected " + progress + " periods.");
      if (progress == 0) {
        String normalstring = getActivity().getResources()
          .getString(R.string.npv1);
        selection.setText(normalstring);
      }
      if (i > progress) {
        while (i > progress) {
          i--;
          EditText editText = (EditText) getActivity()
            .findViewById(i);
          linearLayout.removeView(editText);
        }
      } else {
        while (i < progress) {
          EditText editText = new EditText(getActivity());
          editText.setId(i);
          editText.setLayoutParams(new LayoutParams(
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));
          linearLayout.addView(editText);
          editText.setHint("Cash Flow " + i);
          i++;
        }
      }
    }
    public void onStopTrackingTouch(SeekBar arg0) {
    }
    public void onStartTrackingTouch(SeekBar arg0) {
    }
  });

此代码在通用类区域中:

int i = 0;
EditText r = (EditText) getActivity().findViewById(R.id.npv_rate);
Button calc = (Button) getActivity().findViewById(R.id.npv_calc);
EditText[] DynamicField = new EditText[16];

现在我希望用户将数字输入到那些 edittext 字段中,然后我想对它们进行一些数学运算:Entry / (Math.pow(1+r, i)使用i字段的 id。因此,第一个条目应按以下方式计算:entry/(1+r)^0。这是我尝试过的,但它不起作用。它只是在启动时崩溃。

calc.setOnClickListener(new OnClickListener() {
  public void onClick(View arg0) {
    Double r1 = Double.parseDouble(r.getText().toString());
    EditText editText = (EditText) getActivity().findViewById(i);
    TextView answer = (TextView) getActivity().findViewById(R.id.npv_answer);
    double[] CashFlows;
    CashFlows = new double[i];
    double result = 0;
    CashFlows[i] = (Double.parseDouble(editText.getText()
      .toString())) / (Math.pow(1 + r1, i));
    for (double d : CashFlows) {
      result += d;
    }
    answer.setText("answer is " + result);
  }
});

我做错什么了?顺便说一句,只有最后一个代码段不起作用。如果我评论说一切都很好,我测试了它:) 只是不做任何事情 :)

好的,你可以在这里看到的错误日志的一点背景:http: //pastebin.com/G8iX6Pkm 编辑:整个类文件可以在这里看到:http: //pastebin.com/dxA91dst,整个项目可以在这里找到:https ://github.com/killerpixler/Android-Financial-Calculator.git

类文件是一个片段,当有人单击 Main 活动中的列表项时,该片段会加载到 DetailsActivity 中。就像我说的错误必须在按钮侦听器中,因为它在我添加它之前就已经工作了。

4

1 回答 1

1

NullPointerException是因为您Views使用将getActivity()它们声明为类中的字段的方法进行初始化F_NPV。调用回调后,方法getActivity()方法将返回有效Activity引用onAttach(),因此您初始化视图的方式将不起作用,因为此时(Fragment初始化类的字段时)该方法getActivity将返回null,没有有效引用。进行初始化的正确方法是在onActivityCreated回调中进行:

EditText r;
Button calc;
//...
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    r = (EditText) getActivity().findViewById(R.id.npv_rate);
    calc = (Button) getActivity().findViewById(R.id.npv_calc);
//...

另外,如果可以的话,关于您的代码的一些建议:

您正在从字符串中进行一些双精度解析,检查输入可能是个好主意,这样您就不会抛出NumberFormatException. 例如,如果用户创建了一些EditTexts然后单击计算Button(我知道,这听起来很傻,但用户有可能会这样做(例如我做到了)),你会NumberFormatException在尝试解析时抛出 a空String。而是做一点检查:

public void onClick(View arg0) {
    Double r1 = Double.parseDouble((r.getText().toString())
                    .equals("") ? "0" : r.getText().toString());
    EditText editText = (EditText) getActivity().findViewById(i);
    TextView answer = (TextView) getActivity().findViewById(R.id.npv_answer);
    double[] CashFlows;
    CashFlows = new double[i];
    double result = 0;
    String tmp = editText.getText().toString();
    CashFlows[i] = (Double.parseDouble(tmp.equals("") ? "0" : tmp))
                        / (Math.pow(1 + r1, i));
    //...

此外,即使您在EditText上面的代码中有正确的值,也会抛出一个NullPointerException,因为editText变量是null. 原因while在于您用于创建字段的循环。例如,如果用户将 移动SeekBar到 3,则while循环将运行 3 次,每次递增i值。所以,,,,到目前为止是正确的,但是因为你每次都会i增加最终结果。现在在方法中,您将查找带有 id 的,但由于布局中没有 id ,因此视图将是。012ii4onClickEditTextiEditText4null

另外,试着给你的类起更好的名字,你可能很清楚它们的意思,但是对于阅读你的代码的人来说,你可能会让事情变得更糟(比如 F_PNV、F_PV 等)。

onActivityCreated方法的代码。这应该解决你想要做的事情(如果我明白你想要什么):

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    r = (EditText) getActivity().findViewById(R.id.npv_rate);
    calc = (Button) getActivity().findViewById(R.id.npv_calc);
    final LinearLayout linearLayout = (LinearLayout) getActivity()
            .findViewById(R.id.npv_calcfields);
    SeekBar bar = (SeekBar) getActivity().findViewById(R.id.npv_seekbar);
    final TextView selection = (TextView) getActivity().findViewById(
            R.id.npv_selected);
    bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        public void onProgressChanged(SeekBar seekbar, int progress,
                boolean fromUser) {
            selection
                    .setText("You have selected " + progress + " periods.");
            if (progress == 0) {
                String normalstring = getActivity().getResources()
                        .getString(R.string.npv1);
                selection.setText(normalstring);
                linearLayout.removeAllViews(); // the progress is 0 so
                                                // remove all the views that
                                                // are currently present
            } else {                
                int currentChilds = linearLayout.getChildCount();
                if (currentChilds < progress) {
                    while (currentChilds != progress) {
                        EditText editText = new EditText(getActivity());                        
                        editText.setLayoutParams(new LayoutParams(
                                LayoutParams.FILL_PARENT,
                                LayoutParams.WRAP_CONTENT));
                        linearLayout.addView(editText);
                        currentChilds++;                            
                    }
                } else if (currentChilds > progress) {
                    while (currentChilds != progress) {
                        linearLayout.removeViewAt(linearLayout
                                .getChildCount() - 1);
                        currentChilds--;
                    }
                }
            }
        }

        public void onStopTrackingTouch(SeekBar arg0) {
        }

        public void onStartTrackingTouch(SeekBar arg0) {
        }
    });

    calc.setOnClickListener(new OnClickListener() {

        public void onClick(View view) {
            Double r1 = Double.parseDouble((r.getText().toString())
                    .equals("") ? "0" : r.getText().toString());
            TextView answer = (TextView) getActivity().findViewById(
                    R.id.npv_answer);
            final LinearLayout linearLayout = (LinearLayout) getActivity()
                    .findViewById(R.id.npv_calcfields);
            int size = linearLayout.getChildCount();
            double[] CashFlows = new double[size];
            double result = 0;
            for (int i = 0; i < size; i++) {
                EditText editText = (EditText) linearLayout.getChildAt(i);
                String tmp = editText.getText().toString();
                CashFlows[i] = (Double.parseDouble(tmp.equals("") ? "0"
                        : tmp)) / (Math.pow(1 + r1, i));
            }
            for (double d : CashFlows) {
                result += d;
            }
            answer.setText("answer is " + result);
        }
    });

}
于 2012-07-15T10:26:16.080 回答