title: FragmentTabHost: NullPointerException: Drawable.setState(int[]) on a null object reference
body: <p>As a novice Android programmer I've been trying to learn how to setup a simple tabbed UI. Because I think this is best practice nowadays, I've decided to base my layout on FragmentTabHost, as I'm working with fragments and my main activity is also based on FragmentActivity (through extending AppCompatActivity).</p>
  
  <p>The structure of my test app is as follows: I have a main activity with a linear layout containing a fragment that will be used to show different tabs defined in another layout file. I extended Fragment to create a TabsFragment class that implements this tab UI with FragmentTabHost, based on a different layout. I want to have two tabs: one showing a list of names and one just displaying a Text ( the names are generated through a class that I have tested thoroughly ).</p>
  
  <p>The files I'm using are the following:</p>
  
  <p>MainActivity.java</p>
  
  <pre><code>import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentActivity;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.support.v7.widget.Toolbar;
  import android.util.Log;
  import android.view.Menu;
  import android.view.MenuInflater;
  
  public class MainActivity extends AppCompatActivity {
      private String TAG = "MainActivity";
      private Toolbar appToolbar;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          Log.d ( TAG, "onCreate: setting content view" );
          setContentView ( R.layout.activity_main );
  
          appToolbar = ( Toolbar ) findViewById ( R.id.toolbar );
          setSupportActionBar ( appToolbar );
  
          Log.d ( TAG, "onCreate finished")
      }
  
      @Override
      public boolean onCreateOptionsMenu ( Menu menu ) {
          appToolbar.inflateMenu ( R.menu.menu_actions );
  
          return ( true );
      }
  }
  </code></pre>
  
  <p>TabsFragment.java</p>
  
  <pre><code>import android.app.ListFragment;
  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentTabHost;
  import android.support.v4.app.FragmentManager;
  import android.os.Bundle;
  import android.support.v4.app.FragmentTabHost;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ListAdapter;
  import android.widget.TabHost;
  
  /**
   * Created by Joshua on 12/12/2016.
   */
  
  public class TabsFragment extends Fragment implements TabHost.OnTabChangeListener {
      private String TAG = "TabsFragment";
  
      /* Fixed tags for the different tabs */
      public static final String OVERVIEW_TAB_TAG = "TAB_OVERVIEW";
      public static final String SEARCH_TAB_TAG = "TAB_SEARCH";
  
      /* Objects necessary to build activity views
       */
      private LayoutInflater mInflater; // Used for building View objects in memory from our XML-resources
  
      /* The views and other fragments our fragment will contain and helper variables for accessing them
       */
      private View mRoot; // A reference to the root vie of our fragment
      private FragmentTabHost mFragmentTabHost; // A reference to the tab host ( tab controlling ) view of our fragment
      private String labelOverviewTab = "Overview";
      private String labelSearchTab = "Searhc";
  
      private CustomListFragment overviewTabFragment;
      private TextFragment searchTabFragment;
  
      /* Other fragment bookkeeping variables
       */
      private String mCurrentTab; // Stores the tag of the currently visible tag
  
      /* Data and adapters for our views */
      private Persons personsInfo;
      private ListAdapter namesListAdapter;
  
      /* This method will get executed when the system wants to recreate our view
         i.e. when the user returns or enters our tabs interface
         It will return a reference to the root node of the views tree
       */
      @Override
      public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
          super.onCreateView ( inflater, container, savedInstanceState );
          Log.d ( TAG, "onCreateView: starting ..." );
  
          /* Create all the view objects we need in memory and make sure the references to them in our class are correct
          */
          mRoot = inflater.inflate ( R.layout.tabs_fragment, container, false );
          mFragmentTabHost = ( FragmentTabHost ) mRoot.findViewById ( android.R.id.tabhost );
  
          Log.d ( TAG, "onCreateView: layouts inflated ... Attempting FragmentTabHost setup: ..." );
          mFragmentTabHost.setup ( getContext ( ), getChildFragmentManager ( ), android.R.id.tabcontent );
  
          Log.d ( TAG, "onCreateView: setup finished without errors  ..." );
  
          /* Initialize the tab host and make sure it's aware of all the tabs it has to manage
          */
          TabHost.TabSpec overviewTabSpec = mFragmentTabHost.newTabSpec ( OVERVIEW_TAB_TAG );
          TabHost.TabSpec searchTabSpec = mFragmentTabHost.newTabSpec ( SEARCH_TAB_TAG );
          overviewTabSpec = overviewTabSpec.setContent ( R.id.overviewTab ).setIndicator ( labelOverviewTab );
          searchTabSpec = searchTabSpec.setContent ( R.id.searchTab ).setIndicator ( labelSearchTab );
  
          Log.d ( TAG, "onCreateView: created tab specs with TAG's " + overviewTabSpec.getTag ( ) + " &amp; " + searchTabSpec.getTag ( ) );
  
          Persons personsInfo = new Persons ( );
          personsInfo.addPerson ( "Stanley", "Kubrick", 21 );
          personsInfo.addPerson ( "Steven", "Spielberg", 20 );
          personsInfo.addPerson ( "Quentin", "Tarantino", 18 );
          personsInfo.addPerson ( "Joel", "Coen", 24 );
          personsInfo.addPerson ( "Ethan", "Coen", 26 );
  
          Log.d ( TAG, "onCreateView: initialized data" );
  
          overviewTabFragment = new CustomListFragment ( );
          overviewTabFragment.setFragmentContext ( getContext( ) );
          overviewTabFragment.setDataSource ( personsInfo );
  
          searchTabFragment = new TextFragment ( );
          searchTabFragment.setUniqueTag ( "Search" );
          searchTabFragment.setTabText ( "Here you will be able to SEARCH" );
  
          Log.d ( TAG, "onCreateView: created fragments" );
  
          mCurrentTab = OVERVIEW_TAB_TAG;
  
          Log.d ( TAG, "onCreateView: set current tab variable to " + OVERVIEW_TAB_TAG );
  
          getFragmentManager ( ).beginTransaction ( ).add ( overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
          mFragmentTabHost.addTab ( overviewTabSpec, CustomListFragment.class, null );
          mFragmentTabHost.addTab ( searchTabSpec, TextFragment.class, null );
  
          Log.d ( TAG, "onCreateView: added current tab to fragment manager and added tabs to FragmentTabHost" );
  
          mFragmentTabHost.setCurrentTabByTag ( mCurrentTab );
  
          Log.d ( TAG, "onCreateView: set current tab to " + mCurrentTab );
  
          /* Make sure this fragment will listen to the user slecting a new ta
          */
          Log.d ( TAG, "onCreateView: configuring tab host listener" );
  
          mFragmentTabHost.setOnTabChangedListener ( this );
  
          Log.d ( TAG, "onCreateView finished. Returning " + mRoot );
  
          return ( mRoot );
      }
  
      @Override
      public void onActivityCreated ( Bundle savedInstanceState ) {
          super.onActivityCreated(savedInstanceState);
          setRetainInstance(true);
  
          Log.d(TAG, "onActivityCreated finished" );
      }
  
      @Override
      public void onTabChanged ( String tabID ) {
          /* Get the fragment manager associated with the tab controlling fragment
           */
          Log.d ( TAG, tabID );
          FragmentManager fragmentManager = this.getFragmentManager ( );
          if ( fragmentManager.findFragmentByTag ( tabID ) == null &amp;&amp; mCurrentTab.equals ( OVERVIEW_TAB_TAG ) ) {
              fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, searchTabFragment, SEARCH_TAB_TAG ).commit ( );
              mCurrentTab = SEARCH_TAB_TAG;
          } else if ( fragmentManager.findFragmentByTag ( tabID ) == null &amp;&amp; mCurrentTab.equals ( SEARCH_TAB_TAG ) ) {
              fragmentManager.beginTransaction ( ).replace ( android.R.id.tabcontent, overviewTabFragment, OVERVIEW_TAB_TAG ).commit ( );
              mCurrentTab = OVERVIEW_TAB_TAG;
          }
      }
  }
  </code></pre>
  
  <p>CustomListFragment.java</p>
  
  <pre><code>package com.joshuaindustries.tabtest;
  
  import android.support.v4.app.ListFragment;
  import android.content.Context;
  import android.content.Intent;
  import android.util.Log;
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.ArrayAdapter;
  import android.widget.ListView;
  
  /**
   * Created by Joshua on 18/12/2016.
   */
  
  public class CustomListFragment extends ListFragment {
      String TAG = "CustomListFragment";
  
      Context fragmentContext;
  
      Persons persons;
      ArrayAdapter namesListAdapter;
  
      public void setFragmentContext ( Context fragmentContext ) {
          this.fragmentContext = fragmentContext;
      }
  
      public void setDataSource ( Persons persons ) {
          this.persons = persons;
          namesListAdapter = new ArrayAdapter ( fragmentContext, R.layout.tab_content_list, R.id.list_item_text_view, persons.getFirstNameArray ( ) );
          setListAdapter ( namesListAdapter );
      }
  
      @Override
      public void onListItemClick ( ListView listView, View itemView, int position, long id ) {
          Intent showDetails = new Intent ( fragmentContext, details.class );
  
          listView.getItemAtPosition ( position );
          persons.putFieldsInIntent ( showDetails, position );
  
          startActivity ( showDetails );
      }
  }
  </code></pre>
  
  <p>TextFragment.java</p>
  
  <pre><code>package com.joshuaindustries.tabtest;
  
  import android.support.v4.app.Fragment;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.TabHost;
  import android.widget.TextView;
  
  /**
   * Created by Joshua on 15/12/2016.
   */
  
  public class TextFragment extends Fragment {
      String TAG = "TextFragment";
      String UNIQUE_TAG;
  
      private String mTabText;
  
      private View mRoot;
      private TextView mTextView;
  
      public void setTabText ( String tabText ) {
          mTabText = tabText;
      }
  
      @Override
      public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
          /* Create all the view objects we need in memory and make sure the references to them in our class are correct
           */
          mRoot = inflater.inflate ( R.layout.tab_content, container, false );
          mTextView = ( TextView ) mRoot.findViewById ( R.id.tabTextView );
          mTextView.setText ( mTabText );
  
          return ( mRoot );
      }
  
      public void setUniqueTag ( String tag ) { UNIQUE_TAG = tag; }
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          // this is really important in order to save the state across screen
          // configuration changes for example
          setRetainInstance(true);
      }
  }
  </code></pre>
  
  <p>Persons.java</p>
  
  <pre><code>package com.joshuaindustries.tabtest;
  
  import android.content.Intent;
  
  import java.util.ArrayList;
  
  /**
   * Created by Joshua on 17/12/2016.
   */
  
  public class Persons {
      public final static String PERSON_FIRST_NAME = "PERSON_FIRST_NAME";
      public final static String PERSON_LAST_NAME = "PERSON_LAST_NAME";
      public final static String PERSON_AGE = "PERSON_AGE";
  
      public class Person {
          String firstName;
          String lastName;
          int age;
  
          public Person ( String firstName, String lastName, int age ) {
              this.firstName = firstName; this.lastName = lastName; this.age = age;
          }
  
          public void setFirstName ( String newFirstName ) { firstName = newFirstName; }
          public void setLastName ( String newLastName ) { lastName = newLastName; }
          public void setAge ( int newAge ) { age = newAge; }
  
          public String getFirstName ( ) { return ( firstName ); }
          public String getLastName ( ) { return ( lastName ); }
          public int getAge ( ) { return ( age ); }
      }
  
      ArrayList&lt;Person&gt; listOfPersons;
  
      public Persons ( ) {
          listOfPersons = new ArrayList&lt;Person&gt; ( );
      }
  
      public void addPerson ( String firstName, String lastName, int age ) { listOfPersons.add ( new Person ( firstName, lastName, age ) ); }
  
      public String[] getFirstNameArray ( ) {
          String[] firstNamesArray = new String [ listOfPersons.size ( ) ];
          int index = 0;
  
          for ( Person person : listOfPersons ) {
              firstNamesArray [ index ] = person.getFirstName ( );
              ++ index;
          }
  
          return ( firstNamesArray );
      }
  
      public void putFieldsInIntent ( Intent intent, int position ) {
          Person personAskedFor = listOfPersons.get ( position );
          intent.putExtra ( PERSON_FIRST_NAME, personAskedFor.getFirstName ( ) );
          intent.putExtra ( PERSON_LAST_NAME, personAskedFor.getLastName ( ) );
          intent.putExtra ( PERSON_AGE, personAskedFor.getAge ( ) );
      }
  }
  </code></pre>
  
  <p>activity_main.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/activity_main"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"&gt;
      tools:context="com.joshuaindustries.tabtest.MainActivity"&gt;
  
      &lt;android.support.v7.widget.Toolbar
          android:id="@+id/toolbar"
          android:layout_width="match_parent"
          android:layout_height="?attr/actionBarSize"
          android:background="?attr/colorPrimary"
          android:elevation="4dp"
          android:theme="@style/ThemeOverlay.AppCompat.ActionBar" /&gt;
  
      &lt;SearchView
          android:layout_width="match_parent"
          android:layout_height="wrap_content" /&gt;
      &lt;fragment
          class="com.joshuaindustries.tabtest.TabsFragment"
          android:id="@+id/tabs_fragment"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent" /&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>tabs_fragment.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"&gt;
  
      &lt;LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"&gt;
  
          &lt;TabWidget
              android:id="@android:id/tabs"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:tabStripEnabled="true" /&gt;
  
          &lt;FrameLayout
              android:id="@android:id/tabcontent"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"&gt;
  
              &lt;fragment
                  class="com.joshuaindustries.tabtest.CustomListFragment"
                  android:id="@+id/overviewTab"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" /&gt;
              &lt;fragment
                  android:name="com.joshuaindustries.tabtest.TextFragment"
                  android:id="@+id/searchTab"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" /&gt;
          &lt;/FrameLayout&gt;
      &lt;/LinearLayout&gt;
  &lt;/android.support.v4.app.FragmentTabHost&gt;
  </code></pre>
  
  <p>AndroidManifest.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.joshuaindustries.tabtest"&gt;
  
      &lt;application
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:supportsRtl="true"
          android:theme="@style/Theme.AppCompat.Light.NoActionBar"&gt;
          &lt;activity android:name=".MainActivity"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
  
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
          &lt;activity android:name=".details"&gt;&lt;/activity&gt;
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p>When I build my program and run it, I get the following output in the Run console:</p>
  
  <pre><code>12/19 14:33:22: Launching app
  Cold swapped changes.
  $ adb shell am start -n "com.joshuaindustries.tabtest/com.joshuaindustries.tabtest.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
  Client not ready yet..Connected to process 3007 on device emulator-5554
  I/art: Not late-enabling -Xcheck:jni (already on)
  W/art: Unexpected CPU variant for X86 using defaults: x86
  W/System: ClassLoader referenced unknown path: /data/app/com.joshuaindustries.tabtest-1/lib/x86
  I/InstantRun: Instant Run Runtime started. Android package is com.joshuaindustries.tabtest, real application class is null.
  W/System: ClassLoader referenced unknown path: /data/app/com.joshuaindustries.tabtest-1/lib/x86
  W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
  D/MainActivity: onCreate: setting content view
  D/TabsFragment: onCreateView: starting ...
  D/TabsFragment: onCreateView: layouts inflated ... Attempting FragmentTabHost setup: ...
  D/TabsFragment: onCreateView: setup finished without errors  ...
  D/TabsFragment: onCreateView: created tab specs with TAG's TAB_OVERVIEW &amp; TAB_SEARCH
  D/TabsFragment: onCreateView: initialized data
  D/TabsFragment: onCreateView: created fragments
  D/TabsFragment: onCreateView: set current tab variable to TAB_OVERVIEW
  D/TabsFragment: onCreateView: added current tab to fragment manager and added tabs to FragmentTabHost
  D/TabsFragment: onCreateView: set current tab to TAB_OVERVIEW
  D/TabsFragment: onCreateView: configuring tab host listener
  D/TabsFragment: onCreateView finished. Returning android.support.v4.app.FragmentTabHost{8031d7c VFE...... ......I. 0,0-0,0 #1020012 android:id/tabhost}
  D/TabsFragment: onActivityCreated finished
  W/gralloc_ranchu: Gralloc pipe failed
  
                    [ 12-19 13:33:24.114  3007: 3007 D/         ]
                    HostConnection::get() New Host Connection established 0x9b1a10c0, tid 3007
  I/OpenGLRenderer: Initialized EGL, version 1.4
  D/OpenGLRenderer: Swap behavior 1
  D/AndroidRuntime: Shutting down VM
  E/AndroidRuntime: FATAL EXCEPTION: main
                    Process: com.joshuaindustries.tabtest, PID: 3007
                    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.drawable.Drawable.setState(int[])' on a null object reference
                        at android.widget.TabWidget.dispatchDraw(TabWidget.java:375)
                        at android.view.View.draw(View.java:17071)
                        at android.view.View.updateDisplayListIfDirty(View.java:16050)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.updateDisplayListIfDirty(View.java:16045)
                        at android.view.View.draw(View.java:16834)
                        at android.view.ViewGroup.drawChild(ViewGroup.java:3764)
                        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550)
                        at android.view.View.draw(View.java:17071)
                        at com.android.internal.policy.DecorView.draw(DecorView.java:751)
                        at android.view.View.updateDisplayListIfDirty(View.java:16050)
                        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656)
                        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662)
                        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770)
                        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2796)
                        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2604)
                        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2211)
                        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
                        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
                        at android.view.Choreographer.doCallbacks(Choreographer.java:683)
                        at android.view.Choreographer.doFrame(Choreographer.java:619)
                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
                        at android.os.Handler.handleCallback(Handler.java:751)
                        at android.os.Handler.dispatchMessage(Handler.java:95)
                        at android.os.Looper.loop(Looper.java:154)
                        at android.app.ActivityThread.main(ActivityThread.java:6077)
                        at java.lang.reflect.Method.invoke(Native Method)
                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
  Application terminated.
  </code></pre>
  
  <p>I have absolutely no idea what is causing this NullPointerException since I've confirmed all my layouts are inflated correctly and I can't find anyone with similar problems elsewhere online. I would enormously appreciate some help, especially if you could explain why what I'm doing is wrong.</p>
  
  <p>Thanks in advance, 
  Joshua</p>