Android TabHost.addTab -> Null pointer exception
Asked Answered
L

4

12

Here is my code:

    public class Main extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            TabHost tabHost = new TabHost(this);

            TabHost.TabSpec tab = tabHost.newTabSpec("tab1");
            tab.setIndicator("Tab 1");
            tab.setContent(new TabHost.TabContentFactory() {
                @Override
                public View createTabContent(String tag) {
                    TextView tv = new TextView(Main.this);
                    tv.setText("tab 1 content");
                    return tv;
                }
            });

            tabHost.addTab(tab);

            setContentView(tabHost);
        }
    }

I get this error:

    [...]
    07-13 20:26:49.261: ERROR/AndroidRuntime(625): Caused by: java.lang.NullPointerException
    07-13 20:26:49.261: ERROR/AndroidRuntime(625):     at android.widget.TabHost.addTab(TabHost.java:206)
    07-13 20:26:49.261: ERROR/AndroidRuntime(625):     at test.test.Main.onCreate(Main.java:27)
    [...]

I need to do this by code and I can't use XML. Can anyone help me fix this code please ?

Lamere answered 13/7, 2011 at 20:32 Comment(0)
S
8

You should use TabActivity, it needs same special layout to be set as content (see http://developer.android.com/resources/tutorials/views/hello-tabwidget.html). If you can not use xml you should construct the same content from java code:

public class Main extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TabHost tabHost = new TabHost(this);
    tabHost.setId(android.R.id.tabhost);

    TabWidget widget = new TabWidget(this);
    widget.setId(android.R.id.tabs);

    FrameLayout content = new FrameLayout(this);
    content.setId(android.R.id.tabcontent);

    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    layout.addView(widget);
    layout.addView(content);

    tabHost.addView(layout);

    setContentView(tabHost);

    TabHost.TabSpec tab1 = tabHost.newTabSpec("tab1");
    tab1.setIndicator("Tab 1");
    tab1.setContent(new TabHost.TabContentFactory() {
        @Override
        public View createTabContent(String tag) {
            TextView tv = new TextView(Main.this);
            tv.setText("tab 1 content");
            return tv;
        }
    });

    tabHost.addTab(tab1);

    TabHost.TabSpec tab2 = tabHost.newTabSpec("tab2");
    tab2.setIndicator("Tab 2");
    tab2.setContent(new TabHost.TabContentFactory() {
        @Override
        public View createTabContent(String tag) {
            TextView tv = new TextView(Main.this);
            tv.setText("tab 2 content");
            return tv;
        }
    });

    tabHost.addTab(tab2);

    setContentView(tabHost);
}

}

Stylographic answered 13/7, 2011 at 20:55 Comment(4)
No i need to add a tab into an activity, as a component.Lamere
hm... but TabHost can not work outside TabActivity. The point is to add tabhost to predefined Activity (maybe MapActivity or other), isn't it?Stylographic
no it's for a library. nevermind, if it cannot be done, i'll use something else and program some better tabs myself later.Lamere
TabActivity is deprecated, so I assume it isn't true that TabHost requires it. Can anyone point me at instructions for using TabHost that don't rely on using a deprecated class?Domela
V
44

For people who might wonder about TabActivity being deprecated the documentation says that you need to call setup() before adding tabs, when you don't use a TabActivity.

tabHost.setup();
Vaseline answered 11/2, 2012 at 21:40 Comment(3)
I always forget this bit and end up at your comment. Thanks.Jaban
What a lack of documentation...if you don't find this particular method you're screwed. Awesome, thanks!Hawser
@SvenMenschner Agree. This is a design pattern which is uncommon to every other (android) design pattern. In addition to a constructor call a setup method needs to be called - without parameters. Makes no sense at all to me.Eskilstuna
S
8

You should use TabActivity, it needs same special layout to be set as content (see http://developer.android.com/resources/tutorials/views/hello-tabwidget.html). If you can not use xml you should construct the same content from java code:

public class Main extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TabHost tabHost = new TabHost(this);
    tabHost.setId(android.R.id.tabhost);

    TabWidget widget = new TabWidget(this);
    widget.setId(android.R.id.tabs);

    FrameLayout content = new FrameLayout(this);
    content.setId(android.R.id.tabcontent);

    LinearLayout layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    layout.addView(widget);
    layout.addView(content);

    tabHost.addView(layout);

    setContentView(tabHost);

    TabHost.TabSpec tab1 = tabHost.newTabSpec("tab1");
    tab1.setIndicator("Tab 1");
    tab1.setContent(new TabHost.TabContentFactory() {
        @Override
        public View createTabContent(String tag) {
            TextView tv = new TextView(Main.this);
            tv.setText("tab 1 content");
            return tv;
        }
    });

    tabHost.addTab(tab1);

    TabHost.TabSpec tab2 = tabHost.newTabSpec("tab2");
    tab2.setIndicator("Tab 2");
    tab2.setContent(new TabHost.TabContentFactory() {
        @Override
        public View createTabContent(String tag) {
            TextView tv = new TextView(Main.this);
            tv.setText("tab 2 content");
            return tv;
        }
    });

    tabHost.addTab(tab2);

    setContentView(tabHost);
}

}

Stylographic answered 13/7, 2011 at 20:55 Comment(4)
No i need to add a tab into an activity, as a component.Lamere
hm... but TabHost can not work outside TabActivity. The point is to add tabhost to predefined Activity (maybe MapActivity or other), isn't it?Stylographic
no it's for a library. nevermind, if it cannot be done, i'll use something else and program some better tabs myself later.Lamere
TabActivity is deprecated, so I assume it isn't true that TabHost requires it. Can anyone point me at instructions for using TabHost that don't rely on using a deprecated class?Domela
Q
2

Checking the method TabHost.addTab(...) in the framework source suggests that your TabWidget is not available yet. A TabWidget must be created in code first or by the system when creating a layout and must have an id of android.R.id.tabs.

Quadragesimal answered 13/7, 2011 at 20:42 Comment(0)
H
1

Have you thought about extending TabActivity, and then calling getTabHost() to get the instance of the TabHost? Not sure what your objective is, but this might be worth looking at.

Hypogastrium answered 13/7, 2011 at 20:51 Comment(1)
yes i have, but tabactivity is an activity, and i need a view.Lamere

© 2022 - 2024 — McMap. All rights reserved.