簡體   English   中英

調用findViewById()時,Android ArrayList空指針異常

[英]Android ArrayList Null Pointer Exception when calling findViewById()

我快要用這個把臉撞到牆上了,所以我來找你尋求幫助。

我試圖用包含一些成績數據的ArrayList填充一個片段。 只要該片段為空,該片段就會看起來很好,但是將我的ArrayAdapter連接到它會導致Null Pointer Exception。 我相信該錯誤是由於嘗試查找“ listViewGrades”視圖而引起的,但我不知道該怎么辦。 以下是我的代碼以及堆棧跟蹤:

GradeListFragment.java

public class GradeListFragment extends Fragment{

ArrayAdapter<String> gradeAdapter;
ListView lv;

@Override
public View onCreateView(   LayoutInflater inflater,
                            ViewGroup container,
                            Bundle savedInstanceState){

    Bundle grades = getActivity().getIntent().getExtras();
    ArrayList<String> gradeCategories = grades.getStringArrayList("grades");

    /* The error appears to be here */

    lv = (ListView)getView().findViewById(R.id.listViewGrades);
    gradeAdapter = new ArrayAdapter<String>(getActivity(),  R.layout.line_item, gradeCategories );
    lv.setAdapter(gradeAdapter); 

    return inflater.inflate(R.layout.gradelist_fragment, container, false);
}

GradeListActivity.java

public class GradeListActivity extends Activity{

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gradelist);

    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.add(R.id.gradelist_frag_container, new GradeListFragment());

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        ft.add(R.id.detail_frag_container, new DetailFragment());
    }
    ft.commit();
}

activity_gradelist.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

 <FrameLayout
    android:id="@+id/gradelist_frag_container"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight= "1" />

gradelist_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
    android:id="@+id/listViewGrades"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
</ListView>

MainActivity.java

public class MainActivity extends Activity {

Button showGrades;
GradeCollection grades;
TextView textViewNumericGrade;
TextView textViewLetterGrade;

double numericGrade;
String letterGrade;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    grades = new GradeCollection();

    GradeData e1 = new GradeData("exam", 1 ,80.00, "Exam 1");

    GradeData hw1 = new GradeData("homework", 1, 100.00, "Homework 1");
    GradeData hw2 = new GradeData("homework", 2, 10.00, "Homework 2");

    GradeData q1 = new GradeData("quiz", 1, 5.0, "Quiz 1");
    GradeData q2 = new GradeData("quiz", 2, 5.0, "Quiz 2");
    GradeData q3 = new GradeData("quiz", 3, 4.0, "Quiz 3");

    GradeData l1 = new GradeData("lab", 1, 1.0, "Lab 1");
    GradeData l2 = new GradeData("lab", 2, 1.0, "Lab 2");
    GradeData l3 = new GradeData("lab", 3, 1.0, "Lab 3");
    GradeData l4 = new GradeData("lab", 4, 1.0, "Lab 4");
    GradeData l5 = new GradeData("lab", 5, 1.0, "Lab 5");
    GradeData l6 = new GradeData("lab", 6, 0.0, "Lab 6");
    GradeData l7 = new GradeData("lab", 7, 0.0, "Lab 7");
    GradeData l8 = new GradeData("lab", 8, 1.0, "Lab 8");


    grades.addGrade(e1);
    grades.addGrade(hw1);
    grades.addGrade(hw2);
    grades.addGrade(q1);
    grades.addGrade(q2);
    grades.addGrade(q3);
    grades.addGrade(l1);
    grades.addGrade(l2);
    grades.addGrade(l3);
    grades.addGrade(l4);
    grades.addGrade(l5);
    grades.addGrade(l6);
    grades.addGrade(l7);
    grades.addGrade(l8);


    showGrades =  (Button)findViewById(R.id.buttonShowGrades);
    showGrades.setOnClickListener( new OnClickListener(){
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, GradeListActivity.class);
            intent.putExtra("grades", grades);
            startActivity(intent);
            }
        });

}

activity_main.xml中

<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:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >

<TextView
    android:id="@+id/textViewName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/name"
    android:textAppearance="?android:attr/textAppearanceMedium" />

<RatingBar
    android:id="@+id/ratingBarGrade"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:numStars="4"
    android:stepSize="1.0"
    android:rating="0"/>

<TextView
    android:id="@+id/textViewNumericGrade"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/numericGrade"
    android:textAppearance="?android:attr/textAppearanceMedium" />

<TextView
    android:id="@+id/textViewLetterGrade"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/letterGrade"
    android:textAppearance="?android:attr/textAppearanceMedium" />

<Button
    android:id="@+id/buttonShowGrades"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/buttonViewGrades" />

堆棧跟蹤

03-30 18:02:41.138: E/AndroidRuntime(2288): FATAL EXCEPTION: main
03-30 18:02:41.138: E/AndroidRuntime(2288): Process: bcs421.michaelsheron.hwk.gradeapp.presentation, PID: 2288
03-30 18:02:41.138: E/AndroidRuntime(2288): java.lang.RuntimeException: Unable to start activity ComponentInfo{bcs421.michaelsheron.hwk.gradeapp.presentation/bcs421.michaelsheron.hwk.gradeapp.presentation.GradeListActivity}: java.lang.NullPointerException
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.os.Handler.dispatchMessage(Handler.java:102)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.os.Looper.loop(Looper.java:136)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.ActivityThread.main(ActivityThread.java:5017)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at java.lang.reflect.Method.invokeNative(Native Method)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at java.lang.reflect.Method.invoke(Method.java:515)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at dalvik.system.NativeStart.main(Native Method)
03-30 18:02:41.138: E/AndroidRuntime(2288): Caused by: java.lang.NullPointerException
03-30 18:02:41.138: E/AndroidRuntime(2288):     at bcs421.michaelsheron.hwk.gradeapp.presentation.GradeListFragment.onCreateView(GradeListFragment.java:26)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.Fragment.performCreateView(Fragment.java:1700)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.BackStackRecord.run(BackStackRecord.java:684)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.Activity.performStart(Activity.java:5240)
03-30 18:02:41.138: E/AndroidRuntime(2288):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)
03-30 18:02:41.138: E/AndroidRuntime(2288):     ... 11 more

我要在此先感謝大家抽出寶貴的時間仔細研究這個問題,並向您表示歉意。

首先,必須在GradleListFragment.java中的onCreateView()方法中聲明將實例化所有ui組件的根視圖 ,然后在新創建的視圖上調用findViewById()方法。

將您的代碼轉換為此,然后嘗試按所需方式運行。

@Override
public View onCreateView(LayoutInflater inflater,
                         ViewGroup container,
                         Bundle savedInstanceState) {

    View root = inflater.inflate(R.layout.gradelist_fragment, container, false);

    Bundle grades = getActivity().getIntent().getExtras();
    ArrayList<String> gradeCategories = grades.getStringArrayList("grades");

    lv = (ListView)root.findViewById(R.id.listViewGrades);
    gradeAdapter = new ArrayAdapter<String>(getActivity(),  R.layout.line_item, gradeCategories );
    lv.setAdapter(gradeAdapter);

    return root;
}

您遇到的問題是,您正在嘗試引用尚不存在的視圖中的元素。 Android希望在視圖中找到該組件,但實際上是在您對該視圖進行引用之后才對其進行放大。 因此,引用解析為null。 因此,您將獲得NullPointerException。 相反,請執行以下操作來解決此錯誤:

@Override
public View onCreateView(LayoutInflater inflater,
                            ViewGroup container,
                            Bundle savedInstanceState){

    Bundle grades = getActivity().getIntent().getExtras();
    ArrayList<String> gradeCategories = grades.getStringArrayList("grades");

    View view = inflater.inflate(R.layout.gradelist_fragment, container, false)

    lv = (ListView)view.findViewById(R.id.listViewGrades);
    gradeAdapter = new ArrayAdapter<String>(getActivity(),  R.layout.line_item, gradeCategories );
    lv.setAdapter(gradeAdapter); 

    return view;
}

一個好的設計原則是在onViewCreated()方法中進行這些引用,該方法在創建View后被調用,並且指向所有元素都解析為其期望值。

首先,@ Eric的答案是絕對正確的,您應該保留他建議的代碼。

由於看起來您仍然有原始問題,因此我也將發布此答案。

看來您可能應該創建一個自定義適配器才能執行此處要執行的操作。

我假設您正在嘗試獲取每個GradeData對象中的所有信息,以顯示在ListView的每一行中。

我看到的一個問題是,您在這里傳遞了GradeCollection作為附加項:

GradeCollection grades;
//..........
intent.putExtra("grades", grades);
startActivity(intent);

並嘗試將其檢索為String ArrayList

ArrayList<String> gradeCategories = grades.getStringArrayList("grades");

我猜這時gradeCategories為null,因為GradeCollection對象不是ArrayList<String> ,所以當您嘗試在此處將其提供給ArrayAdapter時:

gradeAdapter = new ArrayAdapter<String>(getActivity(),  R.layout.line_item, gradeCategories );

那可能是您獲得空指針異常的地方。

有幾種不同的解決方法,您最終將需要創建一個自定義適配器,以便可以顯示對象中的數據。 只是為了讓您入門,請嘗試以下操作:

public class MainActivity extends Activity {

Button showGrades;
//GradeCollection grades;
ArrayList<String> grades;
TextView textViewNumericGrade;
TextView textViewLetterGrade;

double numericGrade;
String letterGrade;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //grades = new GradeCollection();

    String e1 = "exam  1  80.00  Exam 1";

    //grades.addGrade(e1);
    grades.add(e1);

    showGrades =  (Button)findViewById(R.id.buttonShowGrades);
    showGrades.setOnClickListener( new OnClickListener(){
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, GradeListActivity.class);
            intent.putExtra("grades", grades);
            startActivity(intent);
            }
        });

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM