java - Android 应用 NPE : Unable to invoke virtual method setOnClickListener on null object

标签 java android android-fragments

我正在构建我的第一个 Android 应用程序(基本计算器),它由一个 Activity 和一个 fragment 组成。应用程序的布局(显示和按钮)在 fragment xml fragment_main.xml 中定义,应在启动时扩充。但是,该应用程序立即因 NPE 而崩溃。我很困惑是应该在 Activity 的 onCreate() 方法中还是在 fragment 类的 onCreateView() 方法中为计算器按钮设置点击监听器。下面的代码和堆栈跟踪。

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.github.idclark.calculator/com.github.idclark.calculator.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

public class MainActivity extends ActionBarActivity implements OnClickListener {

    private TextView mCalculatorDisplay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new CalculatorFragment())
                    .commit();
        }

        mCalculatorDisplay = (TextView) findViewById(R.id.textView);

        findViewById(R.id.AC).setOnClickListener(this);
        findViewById(R.id.plusminus).setOnClickListener(this);
        findViewById(R.id.percent).setOnClickListener(this);
        findViewById(R.id.nine).setOnClickListener(this);
        findViewById(R.id.eight).setOnClickListener(this);
        findViewById(R.id.seven).setOnClickListener(this);
        findViewById(R.id.six).setOnClickListener(this);
        findViewById(R.id.five).setOnClickListener(this);
        findViewById(R.id.four).setOnClickListener(this);
        findViewById(R.id.three).setOnClickListener(this);
        findViewById(R.id.two).setOnClickListener(this);
        findViewById(R.id.one).setOnClickListener(this);
        findViewById(R.id.zero).setOnClickListener(this);
        findViewById(R.id.div).setOnClickListener(this);
        findViewById(R.id.mult).setOnClickListener(this);
        findViewById(R.id.plus).setOnClickListener(this);
        findViewById(R.id.minus).setOnClickListener(this);
        findViewById(R.id.dec).setOnClickListener(this);
        findViewById(R.id.equal).setOnClickListener(this);
    }

@Override
    public void onClick(View v) {

        String buttonPressed = ((Button )v).getText().toString();
        mCalculatorDisplay.setText(buttonPressed);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class CalculatorFragment extends Fragment {

        public CalculatorFragment() {
        }

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

Activity_Main

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container"
    android:layout_width="match_parent" android:layout_height="match_parent"
    tools:context=".MainActivity" tools:ignore="MergeRootFrame" />

主要 fragment

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity$PlaceholderFragment"
    android:orientation="vertical">


<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="0"
    android:id="@+id/textView"
    android:layout_alignEnd="@+id/textView"
    android:textSize="65dp" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/AC"
        android:id="@+id/AC"
        android:layout_weight="0.25" />
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/plusminus"
        android:id="@+id/plusminus"
        android:layout_weight="0.25" />
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/percent"
        android:id="@+id/percent"
        android:layout_weight="0.25" />
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/div"
        android:id="@+id/div"
        android:layout_weight="0.25" />

</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/nine"
        android:id="@+id/nine"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/eight"
        android:id="@+id/eight"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/seven"
        android:id="@+id/seven"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:id="@+id/mult"
        android:text="@string/mult"
        android:layout_weight="0.25"/>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/six"
        android:id="@+id/six"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/five"
        android:id="@+id/five"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/four"
        android:id="@+id/four"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/minus"
        android:id="@+id/minus"
        android:layout_weight="0.25"/>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/three"
        android:id="@+id/three"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/two"
        android:id="@+id/two"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/one"
        android:id="@+id/one"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/plus"
        android:id="@+id/plus"
        android:layout_weight="0.25"/>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="0.5"
        android:text="@string/zero"
        android:id="@+id/zero" />
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/dec"
        android:id="@+id/dec"
        android:layout_weight="0.25"/>
    <Button
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:text="@string/equal"
        android:id="@+id/equal"
        android:layout_weight="0.25"/>
</LinearLayout>

最佳答案

空指针异常的原因是您尝试访问的不同 View (ButtonTextView)不在 Activity 的布局文件中,而是在你的 fragment 的布局文件。

setContentView将布局文件中的所有 View 添加到 Activity 中。

要修复 NPE,您需要在 fragment 的 onCreateView 中实例化 View (ButtonTextView),因为 fragment 的布局文件包含您将要使用的所有 View 。

public class MainActivity extends ActionBarActivity implements OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new CalculatorFragment())
                    .commit();
        }
    }


     /**
         * A placeholder fragment containing a simple view.
         */
    public static class CalculatorFragment extends Fragment  implements OnClickListener {

        private TextView mCalculatorDisplay;

        public CalculatorFragment() {
        }

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


            mCalculatorDisplay = (TextView) rootView.findViewById(R.id.textView);

            rootView.findViewById(R.id.AC).setOnClickListener(this);
            rootView.findViewById(R.id.plusminus).setOnClickListener(this);
            rootView.findViewById(R.id.percent).setOnClickListener(this);
            rootView.findViewById(R.id.nine).setOnClickListener(this);
            rootView.findViewById(R.id.eight).setOnClickListener(this);
            rootView.findViewById(R.id.seven).setOnClickListener(this);
            rootView.findViewById(R.id.six).setOnClickListener(this);
            rootView.findViewById(R.id.five).setOnClickListener(this);
            rootView.findViewById(R.id.four).setOnClickListener(this);
            rootView.findViewById(R.id.three).setOnClickListener(this);
            rootView.findViewById(R.id.two).setOnClickListener(this);
            rootView.findViewById(R.id.one).setOnClickListener(this);
            rootView.findViewById(R.id.zero).setOnClickListener(this);
            rootView.findViewById(R.id.div).setOnClickListener(this);
            rootView.findViewById(R.id.mult).setOnClickListener(this);
            rootView.findViewById(R.id.plus).setOnClickListener(this);
            rootView.findViewById(R.id.minus).setOnClickListener(this);
            rootView.findViewById(R.id.dec).setOnClickListener(this);
            rootView.findViewById(R.id.equal).setOnClickListener(this);

            return rootView;
        }

        @Override
        public void onClick(View v) {

            String buttonPressed = ((Button )v).getText().toString();
            mCalculatorDisplay.setText(buttonPressed);
        }
    }
}

希望对您有所帮助。

关于java - Android 应用 NPE : Unable to invoke virtual method setOnClickListener on null object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28815963/

相关文章:

java - Android - android.view.InflateException : Binary XML file line #9: Error inflating class fragment

android - 从后台返回应用程序时,保存在单例中的静态数据有时为空

android - fragment.getview() 从 Activity 中返回 null

java - SQLite 准备语句的转义替代方案

android - BottomSheetDialogFragment setupDialog 仅限于库组

java - 在Netbean中使用unirest发送短信

java - 如何在 Android Studio 完成之前停止正在运行的方法

android - 如何在 Firebase 中从 android 应用程序创建一个空表?

java - Spring Data Rest 仅使用父路径

java - 创建了 Spring 单例类实例?