Search code examples
androidlistviewandroid-fragmentslayout-inflatercustom-adapter

NullPointer on setAdapter() also triggers InflateException


So, let me explain the scenario first. I have an activity in which gets a string. I pass that string via intent extra to another activity. This second activity will host a fragment that uses that string to perform a search, and then I display my results on a custom ListView.

The problem: First I was getting a NullPointerException when I try to call setAdapter on my list. I google the crap out of this problem, but nothing fixed it. But at the same time I get an InflateException. If I comment out the setAdapter call, then there's no crash. But if I leave it, both causes will be displayed on the log.

Can someone please shine a light on what the problem could be? Here is my code:

Activity that contains the fragment

It only really has the onCreate method...

public class TracksContainerActivity extends AppCompatActivity {

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

Here is the activity_tracks_container layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<include layout="@layout/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/include" />

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_artist_results"
    android:name="com.spadatech.spotifystreamer.fragments.ArtistListFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.spadatech.spotifystreamer.fragments.ArtistListFragment"
    tools:layout="@android:layout/list_content" />

Now, here's the fragment:

public class ArtistListFragment extends Fragment {
private static final String LOG_TAG = ArtistListFragment.class.getSimpleName();

ListView albumsList;
ArrayList<ArtistResults> mArtistResults;
String query;
ArtistArrayAdapter adapter;

public ArtistListFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    query = getActivity().getIntent().getStringExtra("query");
    adapter = new ArtistArrayAdapter(getActivity(), mArtistResults);

    if (savedInstanceState == null || !savedInstanceState.containsKey("artistResults")) {
        mArtistResults = new ArrayList<>();
        performSearch(query);
    } else {
        mArtistResults = savedInstanceState.getParcelableArrayList("artistResults");
    }
}

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

    View v = getActivity().getLayoutInflater().inflate(R.layout.fragment_artist_list, null);
    albumsList = (ListView) v.findViewById(R.id.lvAlbums);
    albumsList.setAdapter(adapter);
    return v;
}

}

And here is the fragment's layout:

<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"
tools:context="com.spadatech.spotifystreamer.fragments.ArtistListFragment">

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/lvAlbums"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

I thought this might help, so here's the log:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.spadatech.spotifystreamer/com.spadatech.spotifystreamer.activities.TracksContainerActivity}: android.view.InflateException: Binary XML file line #11: Error inflating class fragment
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
            at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
            at com.spadatech.spotifystreamer.activities.TracksContainerActivity.onCreate(TracksContainerActivity.java:17)
            at android.app.Activity.performCreate(Activity.java:5990)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
            at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
            at android.widget.ListView.setAdapter(ListView.java:487)
            at com.spadatech.spotifystreamer.fragments.ArtistListFragment.onCreateView(ArtistListFragment.java:72)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:924)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1116)
            at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1218)
            at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2170)
            at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:300)
            at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(AppCompatDelegateImplV7.java:838)
            at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(AppCompatDelegateImplV11.java:34)
            at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:826)
            at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:725)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
            at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
            at com.spadatech.spotifystreamer.activities.TracksContainerActivity.onCreate(TracksContainerActivity.java:17)
            at android.app.Activity.performCreate(Activity.java:5990)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Solution

  • You're passing a null Object List to your adapter.

    Just make the following changes to your code.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        query = getActivity().getIntent().getStringExtra("query");
        if (savedInstanceState == null || !savedInstanceState.containsKey("artistResults")) {
            mArtistResults = new ArrayList<>();
            performSearch(query);
        } else {
            mArtistResults = savedInstanceState.getParcelableArrayList("artistResults");
        }
        adapter = new ArtistArrayAdapter(getActivity(), mArtistResults);
    }