PocketMagic

PocketMagic

Where Technology meets magic


Android
53 Posts
BlackBerry
6 Posts
Electronics
84 Posts
Hardware
142 Posts
High Voltage
57 Posts
Image processing
5 Posts
iPhone
4 Posts
Linux
2 Posts
Nuclear
27 Posts
Optics
11 Posts
Photography
7 Posts
Photoshop
3 Posts
Research
21 Posts
Reviews
19 Posts
Robotics
9 Posts
Security
9 Posts
Software
90 Posts
Symbian
2 Posts
Tubes
23 Posts
Windows Mobile
11 Posts

Sponsored Links


   

Top Articles!


Single Chip Computer | 590 Views | Rate 42.14
Single Chip Computer
AVR SDCard FAT support with FatFS | 14681 Views | Rate 32.2
AVR SDCard FAT support with FatFS
3V to 400V regulated inverter for Geiger counters | 1470 Views | Rate 13.87
3V to 400V regulated inverter for Geiger counters
Electric Fence - 20KV pulses for perimeter defense | 11512 Views | Rate 10.01
Electric Fence - 20KV pulses for perimeter defense

   

News & Updates


2014-10-29, Statie de monitorizare a radiatiei de fond in Timisoara

2014-10-29, uRADMonitor - Online Radiation monitoring station

2014-10-17, Single Chip Computer

2014-07-23, High Voltage Power supply - 140KV

 

  

Android dynamic TAB Control


By Radu Motisan Posted on January 26th, 2010 , 1729 Views (Rate 0.99)



The way to do user interfaces can be different from a platform to another. On Android, you can define the interface using an XML.
For me the best approach is to create the controls on the fly, using the code, instead of some external scripting files.
The reason for this if, of course, the gain in flexibility. For a project I'm currently working on, I had to create a custom TAB Control. I've decided to drop the XML and create everything from the code.

android_tab_control_1 android_tab_control_2 android_tab_control_3

In the "Overridden" onCreate, I check the screen size, to determine whether the android is on landscape or portrait and create a different interface for each case.

  1.  
  2. private Display m_display;
  3. private int m_nScreenW, //screen size
  4. m_nScreenH;
  5.  
  1.  
  2. // -- check screen orientation -- //
  3. m_display = getWindowManager().getDefaultDisplay();
  4. m_nScreenW = m_display.getWidth();
  5. m_nScreenH = m_display.getHeight();
  6. // create interface
  7. View m_vForm;
  8. if (m_nScreenW <= m_nScreenH)
  9. m_vForm = _createTABForm(); // portrait interface
  10. else
  11. m_vForm = _createEmptyForm(); // landscape interface
  12. // show the panel on the screen
  13. setContentView(m_vForm);
  14.  

To create the TAB, there are a few steps we need to follow:
1. create the tabHost and set its parameters
2. create the tabWidget, the container for the clickable tabs
3. create a frameLayout, to hold the views associated to each tab
4. create each tab, using the tabSpec class



To the first tab I'm adding a panel to hold multiple controls, the second tab a listview with few items, and the third tab gets an icon, and only holds a textView control. All in one the code is as follows:

  1.  
  2. /** Create the TAB interface */
  3. private ViewGroup _createTABForm() {
  4. // construct the TAB Host
  5. TabHost tabHost = new TabHost(this);
  6. tabHost.setLayoutParams(
  7. new LinearLayout.LayoutParams(
  8. LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
  9.  
  10. // the tabhost needs a tabwidget, that is a container for the visible tabs
  11. TabWidget tabWidget = new TabWidget(this);
  12. tabWidget.setId(android.R.id.tabs);
  13. tabHost.addView(tabWidget, new LinearLayout.LayoutParams(
  14. LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
  15.  
  16. // the tabhost needs a frame layout for the views associated with each visible tab
  17. FrameLayout frameLayout = new FrameLayout(this);
  18. frameLayout.setId(android.R.id.tabcontent);
  19. frameLayout.setPadding(0, 65, 0, 0);
  20. tabHost.addView(frameLayout, new LinearLayout.LayoutParams(
  21. LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
  22.  
  23. // setup must be called if you are not initialising the tabhost from XML
  24. tabHost.setup();
  25.  
  26. // create the tabs
  27. TabSpec ts1 = tabHost.newTabSpec("TAB_TAG_1");
  28. ts1.setIndicator("TAB-1");
  29. ts1.setContent(new TabHost.TabContentFactory(){
  30. public View createTabContent(String tag)
  31. {
  32. // -- this tab contains multiple control grouped in a panel -- //
  33. LinearLayout panel = new LinearLayout(DynTABSample.this);
  34. panel.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
  35. LayoutParams.WRAP_CONTENT));
  36. panel.setOrientation(LinearLayout.VERTICAL);
  37. // Userid : label and text field
  38. TextView lblUserid = new TextView(DynTABSample.this);
  39. lblUserid.setText("The label above the EditText");
  40. lblUserid.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10f);
  41. lblUserid.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
  42.  
  43. EditText ttfUserid = new EditText(DynTABSample.this);
  44. ttfUserid.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
  45.  
  46. // login button
  47. final Button btnLogin = new Button(DynTABSample.this);
  48. btnLogin.setText("Login");
  49. btnLogin.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
  50. btnLogin.setGravity(Gravity.CENTER);
  51. btnLogin.setOnClickListener(new View.OnClickListener() {
  52. public void onClick(View view) {
  53. Log.d("pocketmagic.net", "_createForm click but");
  54. }
  55. });
  56. // actually adding the views to the panel
  57. // userid
  58. panel.addView(lblUserid);
  59. panel.addView(ttfUserid);
  60. // loginbutton
  61. panel.addView(btnLogin);
  62.  
  63. return panel;
  64. } //TAB 1 done
  65. });
  66. tabHost.addTab(ts1);
  67.  
  68. TabSpec ts2 = tabHost.newTabSpec("TAB_TAG_2");
  69. ts2.setIndicator("TAB-2");
  70. ts2.setContent(new TabHost.TabContentFactory(){
  71. public View createTabContent(String tag)
  72. {
  73. // -- this tab contains a single control - the listview -- //
  74. ListView ls1 = new ListView(DynTABSample.this);
  75. ArrayAdapter<String> adapter = new ArrayAdapter<String>(
  76. DynTABSample.this,
  77. android.R.layout.simple_list_item_1,
  78. new String[]{"item1","item2","item3","item4","item5","item6","item7"});
  79. ls1.setAdapter(adapter);
  80. ls1.setOnCreateContextMenuListener(DynTABSample.this);
  81. return ls1;
  82. }
  83. });
  84. tabHost.addTab(ts2);
  85.  
  86. TabSpec ts3 = tabHost.newTabSpec("TAB_TAG_3");
  87. ts3.setIndicator(" ");
  88. ts3.setContent(new TabHost.TabContentFactory(){
  89. public View createTabContent(String tag)
  90. {
  91. // -- this tab contains a single control - a textview -- //
  92. TextView textAbout = new TextView(DynTABSample.this);
  93. textAbout.setText("About this sample\n\nThis is the Dynamic TAB control sample for Android.\n\n(C)2010 Radu Motisan\nradu.motisan@gmail.com\nwww.pocketmagic.net");
  94. textAbout.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f);
  95. textAbout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
  96. return textAbout;
  97. }
  98. });
  99. tabHost.addTab(ts3);
  100. // -- set the image for tab3, can be used after tab has been created too -- //
  101. ImageView iv = (ImageView)tabHost.getTabWidget().getChildAt(2).findViewById(android.R.id.icon);
  102. if (iv != null) iv.setImageDrawable(getResources().getDrawable(R.drawable.icon));
  103.  
  104. return tabHost;
  105. }
  106.  

Click here to download the source code.



More on PocketMagic:

Google Tango Hackathon in Timisoara | 1255 Views | Rate 6.9
Google Tango Hackathon in Timisoara
How to set the AVR Fusebits | 4062 Views | Rate 6.77
How to set the AVR Fusebits
Atmega8 and Nokia 5110 LCD  | 3385 Views | Rate 5.92
Atmega8 and Nokia 5110 LCD
uRADMonitor - Online Radiation monitoring station | 4055 Views | Rate 5.47
uRADMonitor - Online Radiation monitoring station
Coil Winding machine counter with Atmega8 and Reed relay | 2637 Views | Rate 5.02
Coil Winding machine counter with Atmega8 and Reed relay
Building a robot – Make the robot follow you | 3132 Views | Rate 4.96
Building a robot – Make the robot follow you

56 Responses to “Android dynamic TAB Control”

  1. 1
    venkat:

    Hi i have the tab control name of around 10characters and i have 6 such tabs. Now all the tab control (names)texts are scrolling but i want them to be static and a horizontal scroller for perfect fit of all tabs in the screen. Can u please help me out on this???

    Thanks and Regards,
    Venkat.

  2. 2
    Praveena:

    Hi I want to add data dynamically to linear layout when i click on tab.Give me some suggestions

  3. 3
    Radu Motisan:

    @venkat, can you perhaps put an image showing exactly what you need?

    @Praveena: simply create a new LinearLayout, and your controls when you get the TAB click event.

  4. 4
    praneet:

    you made my day . your implementation of tabs i the best one i have ever seen, it beats that trivial tabs example at android developer network. I tried to have a listview inside the framelayout, but for some stupid reason, the compiler would not detect it from the main.xml file during build time and gave me errors. i got frustrated coz of this. then i ran into ur example, and added a list view dynamically with a custom adapter that i had made…. and it worked like a charm….

    thanks a ton for this awesome article…

  5. 5
    Radu Motisan:

    @praneet: thank you, I’m glad it helped!

  6. 6
    Matt:

    Thank you… finally a real way of making tab content. Everything else is all XML garbage.

  7. 7
    Radu Motisan:

    Thank you, Matt.

  8. 8
    sumit:

    Hi, I have tabs and I am able to set them up properly using xml. I have three tabs basically, one of the tabs when clicked shows a login screen but the problem is when I switch to landscape mode the login page cuts…If I put this inside a scrollview the scrollview is overlapping my tabs and I am unable to see my tabs..To set tabcontent i am using setContent(new Intent()); the approach you followed. let me show you my code.

    public class Maestro extends TabActivity {

    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.maintest);
    addTabs();
    }

    private void addTabs(){
    Resources resources = getResources();

    //since your using the TabActivity you can simply call this method to
    //set up the tabhost make sure to call setup()
    TabHost tabs = (TabHost) findViewById(android.R.id.tabhost);
    tabs.setup();

    //tabspec defines the attributes of the tab
    TabSpec tab;
    //this creates a new tabspec with an id of quiz
    tab = tabs.newTabSpec(“Quiz”);
    //this sets the intent/ activity of the tab when pressed
    tab.setContent(new Intent(this, Quiz.class));
    //this sets the name displayed and the image if you add one
    //tab.setIndicator(“Quiz”);
    tab.setIndicator(“Quiz”);
    //then you add the tab to the tab view
    tabs.addTab(tab);
    tabs.getTabWidget().getChildAt(0).getLayoutParams().height = 30;

    tab = tabs.newTabSpec(“Practice”);
    tab.setContent(new Intent(this, Practice.class));
    tab.setIndicator(“Practice”);
    tabs.addTab(tab);
    tabs.getTabWidget().getChildAt(1).getLayoutParams().height = 30;

    tab = tabs.newTabSpec(“Win”);
    tab.setContent(new Intent(this, AlwaysWin.class));
    tab.setIndicator(“Win”);
    tabs.addTab(tab);
    tabs.getTabWidget().getChildAt(2).getLayoutParams().height = 30;

    tab = tabs.newTabSpec(“TestData”);
    tab.setContent(new Intent(this, TestScreen.class));
    tab.setIndicator(“TestData”);
    tabs.addTab(tab);
    tabs.getTabWidget().getChildAt(3).getLayoutParams().height = 30;

    //sets the current tab
    tabs.setCurrentTab(0);
    //add the tabhost to the main content view

    }
    }

    PRACTICE.JAVA

    public class Practice extends Activity {
    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    }
    }

    main.xml has the login page inside a linear layout

  9. 9
    Sasikumar:

    Hi,
    Nice article :)

    Can you please tell how to set Content for a current tab ?..

    I can able to set content for current tab, but its not changing the view until we change other tab & come back..

  10. 10
    Anshul Agrawal:

    Great article…Very helpful

  11. 11
    Radu Motisan:

    Glad it helped.

  12. 12
    Deps:

    Thanks it helped alot..:-)

  13. 13
    Radu Motisan:

    I’m happy for that.

  14. 14
    JohnC:

    OMG thank you so much for this! Now I can avoid the XML. Even the Google code examples had bugs. And there is a bug when using the eclipse visual editor with tabs. Is there a way to add a menu at the bottom, for buttons, below the tabhost? Every example seems to say that tabhost must fill the screen. But I’m happy now, thanks again. And thanks for replying to an old post. That’s rare too! ;)

  15. 15
    Radu Motisan:

    well, I’m glad this helps, I get notifications for your comments so I try to answer.

    Regarding your question, what kind of menu are you trying to add? Can you show me a picture to better understand? thanks

  16. 16
    JohnC:

    I’m not sure how to attach a screenshot on this form. I downloaded an app called ActionComplete from the Android market and I noticed a tab interface with a bar on the bottom with small buttons for other options. Just programming curiosity since I have seen in a few other apps. http://actioncomplete.com/ has screenshots on their page. My apps are unrelated. Just made me go “hmmmmm”. Thanks again!

  17. 17
    Adhavan J:

    Hi Radu Motisan,
    very nice post.may i know is it possible to have AbsListView instead of ListView.
    my application needs a Tab view and a dynamic Listview which can load according to selected tab.and this particular listview should have alphabetic indexer.(is it possible to have the replica layout of Conntact app)

  18. 18
    Radu Motisan:

    Hello Adhavan,

    Did you try changing the ListView for the AbsListView?

    The code above is quite flexible.

  19. 19
    Adhavan J:

    hi,
    Thank u for your reply,motisan.Now it its working fine after changing to AbsListView(i made a mistake).all my Tab got its own ListView and its is working fine.now i have to implement OnItemClickListener for each listView and i am working on that,do u have any idea to do it?.AnyWay Thank You for this tutorial.

  20. 20
    Radu Motisan:

    You will need to use a different ID for each listview, and check that ID on the click event. Hope this helps.

  21. 21
    Adhavan J:

    Thank You Motisan. Its working yahooooo….. u r the only person in my experience to reply for the question (That too, With correct answers)… thank you once again

  22. 22
    Radu Motisan:

    I’m glad it works!

  23. 23
    RickardH:

    Is there any way to fix the issue with the white line at the bottom of the screen? I.e. it seems like the white line that should cover the bottom of the inactive tabs is instead placed at the bottom of the screen.

  24. 24
    Radu Motisan:

    I’m not quite sure what line are you referring to, please upload a picture

  25. 25
    RickardH:

    I marked the error in the following picture: http://img708.imageshack.us/img708/9393/androidtabcontrol1.jpg
    I used your screenshot since it is seen in them too.

  26. 26
    Carl N:

    @RickardH: I haven’t really looked at the code in that detail but it looks like the content element in the first tab has it’s width set to wrap_content. Try changing that to fill_parent and you should be good to go.

    Ie change this:

    panel.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
    LayoutParams.WRAP_CONTENT));

    To:

    panel.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
    LayoutParams.FILL_PARENT));

  27. 27
    Nirav Dangi:

    hey.. dats realy good way to code XML in JAVA…

  28. 28
    fred:

    Thanks Radu… your tutorial is prolly the most useful when it comes to tabs incorporating various ways to display data in tabs, but still i do have a question:

    how can i display a custom list inside a tab? A list just like the one in TAB2 in your example but extended with some icons next to the text.

    I tried various ways with grid with tables with custom lists, but all fail when i try to create the tab content even if my return type is always a View.

    Here are some code parts related to what i’m trying to do:

    public class UnitSelector extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
    [.......]
    tab3.setContent(new TabData());
    tabs.addTab(tab3);
    [.......]
    }

    class TabData implements TabContentFactory {
    private ListView listview;
    private ArrayList mListItem;

    public View createTabContent(String tag)
    {
    listview = (ListView) findViewById(R.id.list_view);
    mListItem = UnitBO.getUnits();
    listview.setAdapter(new ListAdapter(UnitSelector.this, R.id.list_view,
    mListItem));
    return listview;
    }
    }

    class ListAdapter extends ArrayAdapter {
    private ArrayList mList;
    public ListAdapter(Context context, int textViewResourceId,
    ArrayList list) {
    super(context, textViewResourceId, list);
    this.mList = list;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = vi.inflate(R.layout.list_item, null);
    }
    final UnitBO listItem = mList.get(position);
    if (listItem != null) {
    ((TextView) view.findViewById(R.id.tv_name))
    .setText(listItem.getName());
    (ImageView) view.findViewById(R.id.icon))
    .setImageResource(listItem.getAlerts());

    [.......]
    return view;
    }
    }

  29. 29
    Radu Motisan:

    thanks fred,

    You approach is correct:
    inside public View createTabContent(String tag) you create your listview, you set its custom adapter, and then you return the listview object. That’s it.

    if you need to see how to create a custom listview, please see these two articles:
    http://www.pocketmagic.net/?p=1343
    http://www.pocketmagic.net/?p=1678

    Simply create one of these two complex listviews, and return the object in createTabContent. I did this, it will work with no issue. Still if you get into trouble , let me know.

  30. 30
    Radu Motisan:

    Fred , I just found an example of a TAB Control with custom listview, ready for you to review and use:
    http://www.pocketmagic.net/?p=1398
    This is the control interface for a robot. You’ll see the pictures . Code is also available.

    Hope this helps.

  31. 31
    stark0000:

    Hi, I’d like to know how may i edit the content of a list in a tab, with xml there are IDs, but in the way you did i don’t see how to get back the object ListView after the initialization, i thought something like tabHost.getChildAt().getView()
    but I don’t find the right methods.

    by the way excellent tutorial, it is hard to find tutos explaining how to avoiding xml.

  32. 32
    Radu:

    stark0000, thanks, you can define a global handler for your listview , so you can access it at any time.

  33. 33
    stark0000:

    thanks for answer, I found an easy way to do it with tabHost.getCurrentView() and set tags to Views for externals functions ( view.setTag(“something”); ).

    tanks again for this excellent tuto

  34. 34
    Naba:

    Hi,thankx for the article.I have a specific requirements. I need to split the screen into two(this part i can do using layout) and have to add two tabs on each part of the screen.Is it impossible to add two tabHost in one screen.

  35. 35
    Manoj:

    Very useful

  36. 36
    Aditya:

    Radu,

    Great tutorial! This is most likely the best I have seen in a while.
    I had a question regarding using commands out of the onCreate command–similar to what stark00000 is asking.

    I have a web browser implemented in a tab, but for some reason, it isn’t happy when I call a command outside.

    btnLogin.setOnClickListener(new OnClickListener() {
    public void onClick(View view) {
    openBrowser();
    }
    });

    all that openBrowser does is update the webview.

    private void openBrowser() {
    wv.getSettings().setJavaScriptEnabled(true);
    wv.loadUrl(ttfUserid.getText().toString());
    }
    In the main code, I simply have panel.addView(wv);
    Is there a better way to update?

    Appreciate the help.

  37. 37
    Radu Motisan:

    what error do you get?

  38. 38
    aditya:

    the application works until I press the button.
    Then it crashes telling me that it has stopped working.

  39. 39
    Radu Motisan:

    You need to check the Logcat for the actual error. Without it I don’t have any clue on what goes wrong there.

  40. 40
    aditya:

    sure thing. It’s on a different computer, so I’ll post it in about 10 hours.

  41. 41
    Radu Motisan:

    take your time. when you have it post it here, I’m sure it’s a small issue.
    -Radu

  42. 42
    Aditya:

    So the error says that the Source is not found–in reference to the code in openBrowser().
    I’m assuming that having a variable outside the command isn’t good enough?

  43. 43
    dixit:

    man you are awesome… tut is great….and easy to understand……

    thanks…

  44. 44
    Radu Motisan:

    thanks for your feedback, glad this helped!

  45. 45
    mitchell:

    Project -> Android 2.2 Tab Layout

    http://www.techwavedev.com/?p=14

  46. 46
    shital:

    really good solution

  47. 47
    Amit Saha:

    I move the tahHost at bottom by setting tabWidget.setGravity(Gravity.BOTTOM); after tabWidget.setId(android.R.id.tabs); and also set frameLayout.setPadding(0, 0, 0, 65);

    Now How can I start new activity using this 3 tabs ?
    Please Help.

  48. 48
    cucu:

    hello!

    I would like to modify this source for the mobile in the landscape mode, but I’m not able! could anybody help me?

    Thank you in advance

  49. 49
    Weng Chiun:

    Hey Mr Radu Motisan!

    Thank you so much for uploading this wonderful code!It worked for me!

    I’m pretty new to android programming and was figuring how to get a tab done.

    Thank you once again and I hope that you can guide me along when I have anything in doubts.

    Yours sincerely,
    Weng Chiun

  50. 50
    Weng Chiun:

    Hey Mr Radu Motisan!

    I have 2 questions:

    1. Is it possible to make 2 tabs with the menu like the 2nd tab with different content?
    2. How can I link the “item 1″ in tab 2 to another page (html file)?

    I look forward for your reply and thank you so much!

    Best Regards,
    Weng Chiun

  51. 51
    Weng Chiun:

    Dear Mr Radu Motisan!

    Sorry for sending so many mails, but I thought I have to ask this.

    May I know how to insert my own icon for the tabs?

    I have tried inserting my own png image(search.png) in the drawable folder and did the following changes which after I got an error(it force close the application, after a while it appeared as error in java coding).

    // — set the image for tab3, can be used after tab has been created too — //
    ImageView iv = (ImageView)tabHost.getTabWidget().getChildAt(2).findViewById(android.R.id.icon);
    if (iv != null) iv.setImageDrawable(getResources().getDrawable(R.drawable.search));

    Thank you for your patience and I really look forward for your reply as it is rather urgent right here.

    Best Regards,
    Weng Chiun

  52. 52
    LCD:

    Hi!
    I would like to function to the menu on Tab 2. Isit possible? can anyone help me ?

  53. 53
    LCD:

    Hi!
    I would like to add function to the menu on Tab2. can anyone help me?
    For example: if i click item1, i can call another java file.

  54. 54
    Weng Chiun:

    Dear Mr Radu Motisan,

    Just to update, I am now able to insert the image, but the sizing of the image doesn’t seem to be perfect. Could you tell me how to resize to the desired size?

    Thank you!

    Best Regards

  55. 55
    bill:

    after sdk 3.0, create Tabhost with TabHost tabHost = new TabHost(this, null);

  56. 56
    Multiple errors trying to dynamically create a tab layout video:

    [...] I was trying to follow a sample of code from this link. http://www.pocketmagic.net/2010/01/android-dynamic-tab-control/ [...]

Thank you for commenting. Your comment won't show until approved, which can take some time.

Please copy the string 8Csgcd to the field below: