我正在构建我的第一个 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 (Button
和 TextView
)不在 Activity 的布局文件中,而是在你的 fragment 的布局文件。
setContentView将布局文件中的所有 View 添加到 Activity 中。
要修复 NPE,您需要在 fragment 的 onCreateView
中实例化 View (Button
和 TextView
),因为 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/