Android ArrayList调用findViewById()时出现空指针异常

时间:2015-03-30 22:16:22

标签: java android

我刚刚把这张脸撞到了墙上,所以我来找你帮忙。

我正在尝试使用包含某些成绩数据的ArrayList填充片段。 只要它是空的,片段就会显得很好,但是将ArrayAdapter连接到它会导致空指针异常。我相信错误来自于试图找到我的'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

我想提前感谢所有人花时间仔细研究这个问题,并在遗漏的情况下道歉。

3 个答案:

答案 0 :(得分:0)

首先在方法onCreateView() GradleListFragment.java 中,必须声明根视图,其中将实例化所有ui组件,然后调用{新创建的视图上的{1}}方法。

将您的代码转换为此代码并尝试以您需要的方式运行。

findViewById()

答案 1 :(得分:0)

您遇到的问题是您正在尝试引用视图中尚不存在的元素。 Android希望在View中找到该组件,但在您实际引用该视图后,您仍在对该视图进行充气。因此,引用解析为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之后调用它们,并将所有元素解析为它们的预期值。

答案 2 :(得分:0)

首先,来自@Eric的答案绝对正确,你应该保留他建议的代码。

由于看起来您仍然遇到原始问题,我也会发布此答案。

看起来你应该创建一个自定义适配器,以便做你在这里尝试做的事情。

我假设你试图让每个GradeData对象中的所有信息显示在ListView的每一行中。

我看到的一个问题是你在这里额外传递GradeCollection

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

并尝试将其作为String ArrayList检索

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

我猜测gradeCategories此时为空,因为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);
            }
        });

}