Search code examples
androidtabsandroid-tabhost

Android - How to create tabs on demand using existing layout?


Compulsory background info: I'm building a tablet app for real estate agents to use when quoting homes and buildings. Since a home or an apartment can have any number of rooms, I thought it would be nice to build a tab-based solution that allowed for going room by room and creating one tab per room on demand.

I've been through several tab tutorials but all solutions I've found deal with a predefined number of tabs, and use the deprecated TabHost.

TabHost.TabSpec ourSpec = tabhost.newTabSpec("tag1");
ourSpec.setContent(new TabHost.TabContentFactory()
{

    @Override
    public View createTabContent(String tag)
    {
        // Put some GUI stuff here
        return null;
    }
});

Problem: I want to reuse an existing layout for the new tab, and somehow keep count of how many tabs have been created so far.


Solution

  • After LOTS of research, finally managed to put together something workable.

    Sankar Ganesh's tutorial was very useful.

    MainActivity.java:

    package com.example.workingdynamictabexample;
    
    import android.app.TabActivity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.TabHost;
    
    @SuppressWarnings("deprecation")
    public class MainActivity extends TabActivity
    {
        private TabHost tabHost;
    
        private int z = 0;
    
        private static final int
            ADD_TAB = Menu.FIRST + 11,
            DELETE_TAB = Menu.FIRST + 12;
    
        private String Test = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            this.tabHost = getTabHost();
    
            Intent newRoom = new Intent();
    
            newRoom.setClass(this, RoomActivity.class);
    
            Test = Intent.CATEGORY_LAUNCHER;
    
            Log.d("Test", Test);
    
            tabHost.addTab(
                    tabHost.newTabSpec("Main")
                            .setIndicator("New room")
                            .setContent(newRoom)
                            );
        }
    
        private void addTab()
        {
            Intent newRoom = new Intent();
    
            newRoom.setClass(this, RoomActivity.class);
    
            tabHost.addTab(
                    tabHost.newTabSpec("NewRoomTab")
                            .setIndicator("New room")
                            .setContent(newRoom)
                    );
    
            Log.d("z", Integer.toString(z));
    
            ++z;
        }
    
        // "Boss, we really cannot delete one a'dem tab gubbinz, so we hides 'em."
        private void deleteTab() 
        {
            int position = tabHost.getCurrentTab();
            Log.d("Position", Integer.toString(position));
    
            Log.d("Z val in delete()", Integer.toString(z));
    
            tabHost.getCurrentTabView().setVisibility(View.GONE);
    
            if (position > 0)
            {
                tabHost.setCurrentTab(position + 1);
    
                z -= 1;
    
                if (z < 0)
                {
                    z = 0;
                }
            }
            else if (position == 0)
            {
                tabHost.setCurrentTab(position + 1);
    
                z = 0;
            }
            else if (position == z)
            {
                tabHost.setCurrentTab(z - 1);
    
                Log.d("Z value in final", "lol");
                Log.d("Pos", Integer.toString(position));
                Log.d("Z pos", Integer.toString(z));
            }       
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) 
        {
            menu.add(Menu.NONE, ADD_TAB, Menu.NONE, "New room")
                .setAlphabeticShortcut('a');
    
            return (super.onCreateOptionsMenu(menu));
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            switch (item.getItemId())
            {
            case ADD_TAB:
                addTab();
    
                return (true);
    
            case DELETE_TAB:
                deleteTab();
    
                return (true);
            }
    
            return (super.onOptionsItemSelected(item));
        }
    }
    

    RoomActivity.java:

    package com.example.workingdynamictabexample;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    
    public class RoomActivity extends Activity
    {
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.tabhost);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) 
        {
            return (super.onCreateOptionsMenu(menu));
        }
    }
    

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        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="wrap_content"
                android:tag="tabPane" />
    
                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent">                
                </FrameLayout>
    
        </LinearLayout>
    </TabHost>
    

    tabhost.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        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="wrap_content"
                android:tag="tabPane" 
            />
    
            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
    
                <RelativeLayout
                    android:id="@+id/tab_room"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent">
    
                     <Button
                         android:id="@+id/btnAddTab"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignParentBottom="true"
                         android:layout_alignParentRight="true"
                         android:onClick="addTab"
                         android:text="Add room" />
    
                     <TextView
                         android:id="@+id/lblType"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignParentLeft="true"
                         android:layout_alignParentTop="true"
                         android:layout_marginLeft="20dp"
                         android:layout_marginTop="30dp"
                         android:text="Room type:" />
    
                     <Spinner
                         android:id="@+id/spinnerType"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignBottom="@+id/lblType"
                         android:layout_marginLeft="20dp"
                         android:layout_toRightOf="@+id/lblType" />
    
                     <TextView
                         android:id="@+id/lblWidthX"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignLeft="@+id/lblType"
                         android:layout_below="@+id/lblType"
                         android:layout_marginTop="30dp"
                         android:text="Dimension 1:" />
    
                     <TextView
                         android:id="@+id/lblWidthY"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignLeft="@+id/lblWidthX"
                         android:layout_below="@+id/lblWidthX"
                         android:layout_marginTop="30dp"
                         android:text="Dimension 2:" />
    
                     <EditText
                         android:id="@+id/txtWidthX"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignBaseline="@+id/lblWidthX"
                         android:layout_alignBottom="@+id/lblWidthX"
                         android:layout_alignLeft="@+id/txtWidthY"
                         android:layout_alignParentRight="true"
                         android:ems="10" >
    
                         <requestFocus />
                     </EditText>
    
                     <EditText
                         android:id="@+id/txtWidthY"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignBaseline="@+id/lblWidthY"
                         android:layout_alignBottom="@+id/lblWidthY"
                         android:layout_alignParentRight="true"
                         android:layout_toRightOf="@+id/lblWidthY"
                         android:ems="10" />
    
                     <TextView
                         android:id="@+id/lblFloors"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignLeft="@+id/lblWidthY"
                         android:layout_below="@+id/txtWidthY"
                         android:layout_marginTop="30dp"
                         android:text="Floors:" />
    
                     <EditText
                         android:id="@+id/txtFloors"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_alignBaseline="@+id/lblFloors"
                         android:layout_alignBottom="@+id/lblFloors"
                         android:layout_alignParentRight="true"
                         android:layout_toRightOf="@+id/lblFloors"
                         android:ems="10" />
    
                </RelativeLayout>
    
            </FrameLayout>
        </LinearLayout>
    </TabHost>