【问题标题】:NullPointerException in a fragment problem片段问题中的 NullPointerException
【发布时间】:2019-05-01 19:57:29
【问题描述】:

在过去的几个小时里,我一直在努力寻找问题的答案,但在尝试了不同的方法后,我无法解决我的问题。

我想要的是使用一个 Edittext 和一个对该 edittext 执行某些操作的按钮。这是我在 fragment_main.xml 中的代码:

<android.support.design.widget.TextInputLayout
    android:id="@+id/text_input_email"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:errorEnabled="true">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/email_input"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:hint="Email"
        android:inputType="textEmailAddress"/>

</android.support.design.widget.TextInputLayout>

<Button
    android:id="@+id/send_email_button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Send"/>

还有我在 MainFragment.java 中的代码:

import ...
public class MainFragment extends Fragment {

private TextInputLayout textInputEmail;

public MainFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_main, container, false);

    textInputEmail = (TextInputLayout) view.findViewById(R.id.text_input_email);

    Button send_button = (Button) view.findViewById(R.id.send_email_button);
    send_button.setOnClickListener(view -> buttonSend(view));

    return view;
}

private boolean validateEmail() {
    String emailInput = textInputEmail.getEditText().getText().toString().trim();

    if (emailInput.isEmpty()) {
        textInputEmail.setError("Field can't be empty!");
        return false;
    } else {
        textInputEmail.setError(null);
        return true;
    }
}

public void buttonSend(View v) {
    if (!validateEmail() ) {
        return;
    }

    /*do something*/
}
}

为此,我的任何一个代码都没有出现任何错误,因此我并不真正了解问题所在。我在 MainActivity.java 中收到的警告是“'getText' 可能会在 validateEmail() 方法中的 .getText() 部分产生'java.lang.NullPointerException'”。

希望我解释得很好。感谢任何试图提供帮助的人!

编辑:我相信我解释得不够清楚。我忘了说当我按下发送按钮时,我的应用程序会立即崩溃。这就是我要解决的问题。

编辑 2:这是我认为的“堆栈跟踪”。

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.luka.straingeremailapp, PID: 2728
java.lang.IllegalStateException: Could not find method buttonSend(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:424)
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:381)
    at android.view.View.performClick(View.java:6291)
    at android.view.View$PerformClick.run(View.java:24931)
    at android.os.Handler.handleCallback(Handler.java:808)
    at android.os.Handler.dispatchMessage(Handler.java:101)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7425)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

【问题讨论】:

  • 能否提供应用崩溃时打印的堆栈跟踪信息?
  • 我已经准备好这样做了,你能告诉我具体怎么做吗?
  • @pantank14 粘贴应用崩溃后出现在 android studio 的 logcat 中的日志
  • 我相信我已经将它添加到上面的主要问题中。

标签: java android xml nullpointerexception nullable


【解决方案1】:

对于崩溃:

这是因为android:onClick 属性仅在方法在Activity 上声明时有效,在Fragment 上无效。我建议永远不要使用 android:onClick 属性。

相反,将onCreateView 中的Button 解析为TextInputLayout,并手动调用button.setOnClickListener(view -&gt; buttonSend(view)); 来分配点击监听器。

对于警告:

这是因为TextInputLayout 将其getEditText() 方法声明为@Nullable(这意味着它不保证在调用它时会得到一个非空值)。

原因是TextInputLayout 在膨胀后分配了它的内部EditText(您在XML 布局中声明的TextInputEditText)。

如果您没有将 TextInputEditText 包含为 TextInputLayout 的子项,则 getEditText() 将返回 null。在您的情况下,您可以保证除非您更改该布局,否则您将获得正确的值,因此您可以做的是做出该断言以避免警告:

EditText editText = Objects.requireNonNull(textInputEmail.getEditText());
String emailInput = editText.getText().toString().trim();

【讨论】:

  • 我已将“editText”行添加到 MainFragment.java 中。有警告说:“调用需要 API 级别 19(当前最小值为 16):java.util.Objects#requireNonNull”。运行应用程序时,一切似乎又正常了,但是当我单击发送按钮时,应用程序又崩溃了。
  • 好吧,如果你是 minSdkVersion 16,你只需要在你的项目中定义你自己的。如果您仍然看到问题,则需要提供崩溃的堆栈跟踪。
  • 我相信我已将堆栈跟踪添加到主要问题中。
  • 更新了答案——这个问题与警告无关,但我已经把这两个部分都留给了答案。
  • 我已经删除了Button xml文件的onClick属性,并为它添加了一个id属性。在 MainFragment.java 中,我在 onCreateView 中添加了两行。在添加的第二行中,我收到一个错误,指向“视图”并说“变量'视图'已经在范围内定义”。我该怎么办?我还用新代码更新了主要问题。
【解决方案2】:

这并不是真正的错误,您会发现它实际上很常见。基本上任何不由代码直接控制的 ui 元素(即:片段中的某些东西被单独的活动使用,或在列表适配器中定义的元素。)都会给你这个警告,因为它不能保证 UI 元素存在并且被实例化。
您可以在 .getText() 周围添加一个空检查,以使警告静音并防止它尝试从元素中拉出(如果它确实为空)。

if(textInputEmail != null){
   String emailInput = textInputEmail.getEditText().getText().toString().trim();
}

【讨论】:

  • 我相信我解释得不够好。我忘了说当我按下发送按钮时,我的应用程序会立即崩溃。这就是我要解决的问题。
【解决方案3】:

如果您确定您的代码是正确的,那么只需将您的项目转换为 Kotlin 项目 Android Studio 会为你做这件事 然后异常将成为历史

【讨论】:

    【解决方案4】:

    问题是因为你正在投射:

      textInputEmail = (TextInputLayout) view.findViewById(R.id.text_input_email);
    

    使用:

      textInputEmail = (TextInputEditText) view.findViewById(R.id.text_input_email);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      相关资源
      最近更新 更多