Udacity Sunshine app - 第1课 - 尝试显示模拟ListView时出现NullPointerException

时间:2014-07-23 17:42:01

标签: java android nullpointerexception

我正在接受udacity.com的Android开发培训,以及Sunshine应用程序的实施。我正在使用Android Studio,最新版本默认安装。

我现在应该有一个带有模拟数据的ListView,我得到一个NullPointerException:

07-23 13:12:51.371    1677-1677/com.mydomain.sunshine E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.mydomain.sunshine, PID: 1677
java.lang.NullPointerException
        at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:392)
        at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
        at android.widget.AbsListView.obtainView(AbsListView.java:2263)
        at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
        at android.widget.ListView.onMeasure(ListView.java:1175)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1916)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1113)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1295)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:544)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)

我运行调试器并确定它发生在这里:

            listView.setAdapter(mForeCastAdapter);

当我评论它运行但显然没有显示任何内容,但至少它不会崩溃。

这是我的MainActivity.java的onCreateView():

        @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        String[] forecastArray={
                "foo",
                "bar",
                "baz",
                "fiz",
        };
        List<String> weekForecast = new ArrayList<String> (Arrays.asList(forecastArray));
        mForeCastAdapter = new ArrayAdapter<String>(
                getActivity(),
                R.layout.list_item_forecast,
                R.id.listview_forecast,
                weekForecast);
        ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
        listView.setAdapter(mForeCastAdapter);
        return rootView;
    }

这是我的fragment_main.xml:

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

<ListView
    android:id="@+id/listview_forecast"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" /></FrameLayout>

最后这是我的list_item_forecast.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
/>

谢谢!

2 个答案:

答案 0 :(得分:2)

变化:

mForeCastAdapter = new ArrayAdapter<String>(
                getActivity(),
                R.layout.list_item_forecast,
                R.id.listview_forecast,
                weekForecast);

为:

mForeCastAdapter = new ArrayAdapter<String>(
                getActivity(),
                R.layout.list_item_forecast,
                weekForecast);

您正在使用的构造函数中的ID参数应该是行布局中TextView的ID。但是,只有在行布局超过TextView时才需要这样做。在你的情况下:

  • 行布局仅为TextView,因此您无需提供ID

  • 您提供的ID不适用于行布局中的TextView,而是适用于其他地方的ListView

答案 1 :(得分:0)

如果上述解决方案不适合您,并且您正在物理设备上进行测试,请检查纵向和横向布局是否都声明了ListView。 AS可能会为您创建这两个文件,如果仅将ListView添加到一个文件,然后在测试期间切换方向,则会发生NPE。