2015-03-02 46 views
1

我正在構建我的第一個Android應用程序(基本計算器),它由一個Activity和一個片段組成。應用程序的佈局(顯示和按鈕)在片段xml fragment_main.xml中定義,應在啓動時充氣。然而,該應用程序立即與NPE墜毀。我很困惑我是否應該爲活動的onCreate()方法或片段類的onCreateView()方法中的計算器按鈕設置點擊偵聽器。下面的代碼和堆棧跟蹤。Android應用程序NPE:無法在空對象上調用虛擬方法setOnClickListener

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_Main

<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> 

+0

它應該在片段的onCreateView。 – Sush 2015-03-02 17:35:49

+0

其中一個視圖爲空。確保它們都在佈局中,或者張貼在XML中供我們查看。 – jvrodrigues 2015-03-02 17:50:25

+0

@jvrodrigues我用xml更新了這個問題 – idclark 2015-03-03 01:20:54

回答

1

的原因空指針異常是您試圖訪問的型動物的意見(Button S和TextView)是不是在你的活動的佈局文件,但在你的Fragment的佈局文件。

setContentView將佈局文件中的所有視圖添加到活動中。

要修復NPE,您需要實例化片段的onCreateView中的視圖(Button s和TextView),因爲片段的佈局文件包含要使用的所有視圖。

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); 
     } 
    } 
} 

我希望這會有所幫助。

+0

用這個我得到了一個空的(全灰色沒有文字)屏幕,但該應用程序不會拋出NPE。我是否需要單獨實例化每個按鈕?當我嘗試從片段類調用'setContentView'時,它給出了一個編譯錯誤'非靜態方法不能從靜態上下文中調用' – idclark 2015-03-03 12:35:09

+0

'all grey no text'是什麼意思?按鈕顯示?除非你想使用按鈕,否則你已經實例化它併爲它設置一個'onClickListener'。對於片段,你只需要膨脹佈局,而不是'setContentView'。 – iRuth 2015-03-03 15:44:49

+1

我的意思是既沒有出現'TextView'或'Button's。我通過在片段佈局xml中將類名更新爲'tools:context =「。MainActivity $ CalculatorFragment」「來修復它。 – idclark 2015-03-03 23:30:22

1

您應該重寫FragmentonViewCreated()因爲它保證所有View s的實例。

CalculatorFragment創建一個字段來存儲OnClickListener被分配到你的按鈕,你可以做如下所示:

public static class CalculatorFragment extends Fragment { 
    OnClickListener mListener = null; 
    public CalculatorFragment(OnClickListener listener) { 
     mListener = listener; 
    } 
    //et cetera 

在活動的onCreate()在創建CalculatorFragment時必須指定OnClickListener

if (savedInstanceState == null) { 
    getSupportFragmentManager().beginTransaction() 
      .add(R.id.container, new CalculatorFragment(this)) 
      .commit(); 
} 

在被覆蓋的onViewCreated(),使用getView()度日012返回所以大多數電話變得像 getView().findViewById(R.id.the_id).setOnClickListener(this);

findViewById in fragment android就看你如何使用findViewById

相關問題