Zelter Ady
Zelter Ady

Reputation: 6338

android TabHost inside a LinearLayout

After searching for a solution I decided to re-ask a question already asked here.

I have a TabHost control, and I need to put it inside other Layout (LinearLayout). I tuck the example that google gives us (http://developer.android.com/resources/tutorials/views/hello-tabwidget.html) and did the same with the only difference that the TabHost is not the root of the layout and the activity class that display the view doesn't extend TabActivity, but Activity

My xml is this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TabHost android:id="@+id/tabhost"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <LinearLayout android:orientation="vertical"
            android:layout_width="fill_parent" android:layout_height="fill_parent"
            android:padding="5dp">
            <TabWidget android:id="@android:id/tabs"
                android:layout_width="fill_parent" android:layout_height="53px"
                android:tabStripEnabled="false" android:layout_margin="1px"
                android:background="#222222" />
            <FrameLayout android:id="@android:id/tabcontent"
                android:layout_width="fill_parent" android:layout_height="fill_parent"
                android:padding="5dp" />
        </LinearLayout>
    </TabHost>
</LinearLayout>

and the java class is this:

public class TabsExampleActivity extends Activity {

    TabHost tabHost;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initTabs();

    }


    private void initTabs() {
        Resources res = getResources();                     // Resource object to get Drawables
        tabHost = (TabHost) findViewById(R.id.tabhost);     // The activity TabHost

        TabHost.TabSpec spec;                               // Resusable TabSpec for each tab
        Intent intent;                                      // Reusable Intent for each tab        

        intent = new Intent("eu.pkg.tabsExample.BuildingTabActivity");
        spec = tabHost.newTabSpec("text").setIndicator("",
                          res.getDrawable(R.drawable.tab_text_selector))
                      .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, ClipArtTabActivity.class);
        spec = tabHost.newTabSpec("clipart").setIndicator("",
                          res.getDrawable(R.drawable.tab_clipart_selector))
                      .setContent(intent);
        tabHost.addTab(spec);


        intent = new Intent().setClass(this, FrameSelectorTabActivity.class);
        spec = tabHost.newTabSpec("frame").setIndicator("",
                          res.getDrawable(R.drawable.tab_frame_selector))
                      .setContent(intent);
        tabHost.addTab(spec);



        intent = new Intent().setClass(this, BgSelectorTabActivity.class);
        spec = tabHost.newTabSpec("bg").setIndicator("",
                          res.getDrawable(R.drawable.tab_bg_selector))
                      .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, BuildingTabActivity.class);
        spec = tabHost.newTabSpec("build").setIndicator("",
                          res.getDrawable(R.drawable.tab_build_selector))
                      .setContent(intent);
        tabHost.addTab(spec);

        tabHost.setCurrentTab(4);
    }
}

If I use as base activity the TabActivity, and I use the TabHost as root, then the code works well, I see the tabs... etc.

The issue appears only if I extend Activity and the error is:

04-11 18:53:38.874: ERROR/AndroidRuntime(32539): java.lang.RuntimeException: Unable to start activity ComponentInfo{eu.pkg.tabsExample/eu.pkg.tabsExample.TabsExampleActivity}: java.lang.NullPointerException

The question is: How to host a TabHost inside a LinearLayout?

Edit:

After changing as suggested in comments, the log cat errors are:

04-11 20:52:01.993: ERROR/imdg81(28747): IsShutDownStarted() 04-11 20:52:01.999: ERROR/SensorManager(28747): registerListener 4:gp2a Light Sensor delay:240 04-11 20:52:01.999: ERROR/SensorManager(28747): =======>>>Sensor Thread RUNNING <<<======== 04-11 20:52:02.075: ERROR/imdg81(28747): IsShutDownStarted() 04-11 20:52:02.284: ERROR/LockPatternKeyguardView(28747): Phone is boot completed. so can send broadcast message for music player 04-11 20:52:05.507: ERROR/jdwp(3675): Failed writing handshake bytes: Broken pipe (-1 of 14) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): FATAL EXCEPTION: main 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): java.lang.RuntimeException: Unable to start activity ComponentInfo{eu.pkg.tabsExample/eu.pkg.tabsExample.TabsExampleActivity}: java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager activityGroup)'? 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.os.Handler.dispatchMessage(Handler.java:99) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.os.Looper.loop(Looper.java:123) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.ActivityThread.main(ActivityThread.java:4627) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at java.lang.reflect.Method.invokeNative(Native Method) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at java.lang.reflect.Method.invoke(Method.java:521) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at dalvik.system.NativeStart.main(Native Method) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): Caused by: java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager activityGroup)'? 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:654) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.widget.TabHost.setCurrentTab(TabHost.java:328) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.widget.TabHost.addTab(TabHost.java:213) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at eu.pkg.tabsExample.TabsExampleActivity.initTabs(TabsExampleActivity.java:43) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at eu.pkg.tabsExample.TabsExampleActivity.onCreate(TabsExampleActivity.java:27) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 04-11 20:52:05.609: ERROR/AndroidRuntime(3675): ... 11 more

Upvotes: 1

Views: 10445

Answers (4)

Zelter Ady
Zelter Ady

Reputation: 6338

Problem solved. The correct solution, as given by the user 207 in one of the comments, from another stackoverflow question is this:

This is the XML:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TabHost android:id="@android:id/tabhost"  
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <LinearLayout android:orientation="vertical"
            android:layout_width="fill_parent" android:layout_height="fill_parent"
            android:padding="5dp">
            <TabWidget android:id="@android:id/tabs"
                android:layout_width="fill_parent" android:layout_height="53px"
                android:tabStripEnabled="false" android:layout_margin="1px"
                android:background="#222222" />
            <FrameLayout android:id="@android:id/tabcontent"
                android:layout_width="fill_parent" android:layout_height="fill_parent"
                android:padding="5dp" />
        </LinearLayout>
    </TabHost>
</LinearLayout>

and java file:

package eu.pkg.tabsExample;

import android.app.Activity;
import android.app.LocalActivityManager;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TabHost;

public class TabsExampleActivity extends Activity {

    TabHost tabHost;
    LocalActivityManager mLocalActivityManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initTabs(savedInstanceState);
    }

    @Override
    protected void onResume() {
        mLocalActivityManager.dispatchResume(); 
        super.onResume();
    }

    @Override
    protected void onPause() {
        mLocalActivityManager.dispatchPause(isFinishing());
        super.onPause();
    }

    private void initTabs(Bundle savedInstanceState) {
        Resources res = getResources();                     // Resource object to get Drawables
        tabHost = (TabHost) findViewById(android.R.id.tabhost);     // The activity TabHost
        mLocalActivityManager = new LocalActivityManager(this, false);
        mLocalActivityManager.dispatchCreate(savedInstanceState);
        tabHost.setup(mLocalActivityManager);

        TabHost.TabSpec spec;                               // Resusable TabSpec for each tab
        Intent intent;                                      // Reusable Intent for each tab        

        intent = new Intent("eu.pkg.tabsExample.BuildingTabActivity");
        spec = tabHost.newTabSpec("text").setIndicator("",
                          res.getDrawable(R.drawable.tab_text_selector))
                      .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, ClipArtTabActivity.class);
        spec = tabHost.newTabSpec("clipart").setIndicator("",
                          res.getDrawable(R.drawable.tab_clipart_selector))
                      .setContent(intent);
        tabHost.addTab(spec);


        intent = new Intent().setClass(this, FrameSelectorTabActivity.class);
        spec = tabHost.newTabSpec("frame").setIndicator("",
                          res.getDrawable(R.drawable.tab_frame_selector))
                      .setContent(intent);
        tabHost.addTab(spec);



        intent = new Intent().setClass(this, BgSelectorTabActivity.class);
        spec = tabHost.newTabSpec("bg").setIndicator("",
                          res.getDrawable(R.drawable.tab_bg_selector))
                      .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(this, BuildingTabActivity.class);
        spec = tabHost.newTabSpec("build").setIndicator("",
                          res.getDrawable(R.drawable.tab_build_selector))
                      .setContent(intent);
        tabHost.addTab(spec);

        tabHost.setCurrentTab(4);
    }
}

the magic behind the scene is in those 4 lines of code:

    tabHost = (TabHost) findViewById(android.R.id.tabhost);     // The activity TabHost
    mLocalActivityManager = new LocalActivityManager(this, false);
    mLocalActivityManager.dispatchCreate(savedInstanceState);
    tabHost.setup(mLocalActivityManager);

Thank you all for contribution to this answer.

Upvotes: 6

207
207

Reputation: 3804

This will fix your error.

In addition: I just read that you want to extent from Activity instead of TabActivity because you're trying to achieve "nested tabs". It sould not be a problem having a TabActivity within another TabActivity. Haven't done this before but I don't see any troubles that may come off. There is no difference in adding an Activity or TabActivity as tab content. You may give it a try

Upvotes: 0

Shubhayu
Shubhayu

Reputation: 13552

Change this particular line

TabHost android:id="@+id/tabhost"

to

TabHost android:id="@android:id/tabhost"

EDIT

Also add after the following line

tabHost = (TabHost) findViewById(R.id.tabhost);
tabHost.setup();

Upvotes: 0

dcanh121
dcanh121

Reputation: 4695

Here is the solution if you are using Activity instead of extending TabActivity

https://stackoverflow.com/a/5098774/563306

Upvotes: 0

Related Questions