{"id":1481,"date":"2016-02-15T08:11:13","date_gmt":"2016-02-15T08:11:13","guid":{"rendered":"http:\/\/www.mplx.de\/Fremdgesteuert\/?p=1481"},"modified":"2019-09-04T04:43:16","modified_gmt":"2019-09-04T04:43:16","slug":"tabhost-in-android-apps","status":"publish","type":"post","link":"http:\/\/www.mplx.de\/Fremdgesteuert\/2016\/02\/15\/tabhost-in-android-apps\/","title":{"rendered":"TabHost in Android Apps"},"content":{"rendered":"<div id=\"attachment_1486\" style=\"width: 179px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/2016\/02\/15\/tabhost-in-android-apps\/statistics-android-devices\/\" rel=\"attachment wp-att-1486\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1486\" class=\"wp-image-1486 size-medium\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Statistics-Android-devices-169x300.png\" alt=\"TabHost displaying statistics in Android device\" width=\"169\" height=\"300\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Statistics-Android-devices-169x300.png 169w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Statistics-Android-devices.png 540w\" sizes=\"auto, (max-width: 169px) 100vw, 169px\" \/><\/a><p id=\"caption-attachment-1486\" class=\"wp-caption-text\">TabHost displaying statistics in Android device<\/p><\/div>\n<p align=\"JUSTIFY\">The &#8216;Fitness Manager&#8217; App provides several statistics for the user in order to check the workout progress. The different statistics should be displayed in a TabHost. A TabHost is a container for a tabbed window view. The TabHost holds two children. One child contains a set of tab labels that the user clicks to select a specific tab. The other child contains a FrameLayout object that displays the contents of that page. The TabHost integrated in the Fitness App should meet the following further requirements:<\/p>\n<ul>\n<li>\n<p align=\"JUSTIFY\">Every tab displays a button bar which contains a different amount of buttons depending on the selected tab.<\/p>\n<\/li>\n<li>\n<p align=\"JUSTIFY\">Every tab contains an area where the corresponding statistics are plotted.<\/p>\n<\/li>\n<\/ul>\n<p align=\"JUSTIFY\">First I had to define the XML Layout for the TabHost in a XML Layout file. In Android Studio the container for TabHost is provided in the palette of the Android Studio designer. The TabHost can be simply inserted in an empty activity by drag and drop.<\/p>\n<p align=\"JUSTIFY\">When integrating the container for TabHost, first the TabHost itself is defined in the XML Layout definition. The TabHost contains a RelativeLayout of the same size.<\/p>\n<div id=\"attachment_1490\" style=\"width: 360px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/tabhost-layout-definition\/\" rel=\"attachment wp-att-1490\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1490\" class=\"wp-image-1490 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-Layout-definition.png\" alt=\"TabHost XML Layout definition\" width=\"350\" height=\"165\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-Layout-definition.png 350w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-Layout-definition-300x141.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/a><p id=\"caption-attachment-1490\" class=\"wp-caption-text\">TabHost XML Layout definition<\/p><\/div>\n<p align=\"JUSTIFY\">The RelativeLayout of the TabHost contains the definition of a TabWidget. The TabWidget displays a list of tab labels representing each page in the parent&#8217;s tab collection. The container object for this widget is TabHost. When the user selects a tab, this object sends a message to the parent container TabHost, to tell it to switch the displayed page.<\/p>\n<div id=\"attachment_1492\" style=\"width: 351px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/tabwidget-layout-definition\/\" rel=\"attachment wp-att-1492\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1492\" class=\"wp-image-1492 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabWidget-Layout-definition.png\" alt=\"TabWidget XML Layout definition\" width=\"341\" height=\"96\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabWidget-Layout-definition.png 341w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabWidget-Layout-definition-300x84.png 300w\" sizes=\"auto, (max-width: 341px) 100vw, 341px\" \/><\/a><p id=\"caption-attachment-1492\" class=\"wp-caption-text\">TabWidget XML Layout definition<\/p><\/div>\n<p align=\"JUSTIFY\">The XML Layout definition for TabWidget contains the attribute <i>android:id<\/i> set to the value <i>@android:id\/tabs.<\/i> This value cannot be changed and therefore the TabWidget cannot be accessed programmatically by using the function <i>findViewbyId<\/i>.<\/p>\n<p align=\"JUSTIFY\">Additionally the RelativeLayout of the TabHost contains a FrameLayout. The FrameLayout is used for displaying the content of the TabHost.<\/p>\n<div id=\"attachment_1485\" style=\"width: 340px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/framelayout-layout-definition\/\" rel=\"attachment wp-att-1485\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1485\" class=\"wp-image-1485 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/FrameLayout-Layout-definition.png\" alt=\"FrameLayout XML Layout definition\" width=\"330\" height=\"70\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/FrameLayout-Layout-definition.png 330w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/FrameLayout-Layout-definition-300x64.png 300w\" sizes=\"auto, (max-width: 330px) 100vw, 330px\" \/><\/a><p id=\"caption-attachment-1485\" class=\"wp-caption-text\">FrameLayout XML Layout definition<\/p><\/div>\n<p align=\"JUSTIFY\">The XML Layout definition for FrameLayout also contains the attribute <i>android:id.<\/i> The value for the attribute <i>android:id<\/i> is set to the value <i>@android:id\/tabs.<\/i> This value cannot be changed either and therefore cannot be accessed programmatically by using the function <i>findViewbyId<\/i>. For every tab added to the container TabHost a LinearLayout is defined in the XML Layout definition of the FrameLayout. There you have the base frame for a TabHost. Now the LinearLayouts in the FrameLayouts can be filled with view elements like every other convenient view. GridLayouts or LinearLayouts can be inserted into the LinarLayout for ButtonBars or mobile forms. ImageViews, ScrollViews or ListViews can also be embedded by the LinearLayouts of the FrameLayout.<\/p>\n<p align=\"JUSTIFY\">After finishing the XML Layout definition of the TabHost, the TabHost has to be instantiated programmatically in the <i>onCreate<\/i> method of the corresponding activity. The TabHost instantiation includes the definition of the single tabs. The tab of a TabHost has a tab indicator, content and a tag that is used to keep track of it. After declaring objects for every tab, the content of the tab is assigned by specifing the id of the corresponding view and the label is set as tab indicator.<\/p>\n<div id=\"attachment_1489\" style=\"width: 427px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/tabhost-instantiation\/\" rel=\"attachment wp-att-1489\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1489\" class=\"wp-image-1489 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-instantiation.png\" alt=\"TabHost instantiation\" width=\"417\" height=\"364\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-instantiation.png 417w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-instantiation-300x262.png 300w\" sizes=\"auto, (max-width: 417px) 100vw, 417px\" \/><\/a><p id=\"caption-attachment-1489\" class=\"wp-caption-text\">TabHost instantiation<\/p><\/div>\n<p align=\"JUSTIFY\">In order to handle the user input action, when a different tab is selected, a set<i>OnTabChangedListener<\/i> must be implemented in the <em>onCreate<\/em> function of the corresponding activity. In this Listener the content of the selected tab can be set.<\/p>\n<div id=\"attachment_1491\" style=\"width: 492px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/tabhost-setontabchangedlistener\/\" rel=\"attachment wp-att-1491\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1491\" class=\"wp-image-1491 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-setOnTabChangedListener.png\" alt=\"TabHost: setOnTabChangedListener\" width=\"482\" height=\"321\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-setOnTabChangedListener.png 482w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabHost-setOnTabChangedListener-300x200.png 300w\" sizes=\"auto, (max-width: 482px) 100vw, 482px\" \/><\/a><p id=\"caption-attachment-1491\" class=\"wp-caption-text\">TabHost: setOnTabChangedListener<\/p><\/div>\n<p align=\"JUSTIFY\">Now the basic implementation of the TabHost is finished.<\/p>\n<p align=\"JUSTIFY\">But if your app should resize the content of the TabHost depending on the Android device or the orientation of the Android device, then you have to implement a runnable with <i>post<\/i> functionality. There the content of the tab must be accessed and the tab must be resized, which cannot be handled easily by calling <i>findViewbyId <\/i>as I already mentioned. The content of the tab can only be accessed via the container TabHost by <i>host.getTabContentView().getChildAt(int i)<\/i>. The same access point is valid for the TabWidget of the TabHost: <i>host.getTabWidget(). getChildAt(int i).<\/i> Then for example the LayoutParams of the TabWidget or the content of the TabHost can be set.<\/p>\n<div id=\"attachment_1487\" style=\"width: 693px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/tabcontent-layoutparams\/\" rel=\"attachment wp-att-1487\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1487\" class=\"wp-image-1487 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabContent-LayoutParams.png\" alt=\"TabContent LayoutParams definition\" width=\"683\" height=\"82\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabContent-LayoutParams.png 683w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabContent-LayoutParams-300x36.png 300w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/TabContent-LayoutParams-588x71.png 588w\" sizes=\"auto, (max-width: 683px) 100vw, 683px\" \/><\/a><p id=\"caption-attachment-1487\" class=\"wp-caption-text\">TabContent LayoutParams definition<\/p><\/div>\n<p align=\"JUSTIFY\">Last issue I want to point out concerning TabHost is the Android device orientation. If the user rotates the Android device while displaying a TabHost in an App, then the tab is always set to the first tab of the TabHost with every rotation, no matter which tab was selected previously to the screen rotation. In order to solve this issue I did overwrite the function onSaveInstanceState of the activity and saved the current tab value.<\/p>\n<div id=\"attachment_1484\" style=\"width: 503px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/activity-onsaveinstancestate\/\" rel=\"attachment wp-att-1484\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1484\" class=\"wp-image-1484 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Activity-onSaveInstanceState.png\" alt=\"Activity onSaveInstanceState implementation\" width=\"493\" height=\"76\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Activity-onSaveInstanceState.png 493w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Activity-onSaveInstanceState-300x46.png 300w\" sizes=\"auto, (max-width: 493px) 100vw, 493px\" \/><\/a><p id=\"caption-attachment-1484\" class=\"wp-caption-text\">Activity onSaveInstanceState implementation<\/p><\/div>\n<p align=\"JUSTIFY\">Therefore I could access the savedInstanceState now in the <em>onCreate<\/em> and <em>onConfigurationChanged<\/em> functions of the activity and set the tab selected previously to a screen rotation.<\/p>\n<div id=\"attachment_1483\" style=\"width: 386px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.mplx.de\/Fremdgesteuert\/activity-access-savedinstancestate\/\" rel=\"attachment wp-att-1483\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1483\" class=\"wp-image-1483 size-full\" src=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Activity-access-savedInstanceState.png\" alt=\"Activity access of savedInstanceState\" width=\"376\" height=\"37\" srcset=\"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Activity-access-savedInstanceState.png 376w, http:\/\/www.mplx.de\/Fremdgesteuert\/wp-content\/uploads\/2016\/02\/Activity-access-savedInstanceState-300x30.png 300w\" sizes=\"auto, (max-width: 376px) 100vw, 376px\" \/><\/a><p id=\"caption-attachment-1483\" class=\"wp-caption-text\">Activity access of savedInstanceState<\/p><\/div>\n<p align=\"JUSTIFY\">And done \ud83d\ude42<\/p>\n<p align=\"JUSTIFY\">If you have any questions, any improvement suggestions for the implementation (I mentioned that this is my first Android App) or any improvement suggestions for my English, I really would appreciate if you can leave me a comment.<\/p>\n<p align=\"JUSTIFY\">And I would even more appreciate if you like to check out the <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=de.mplx.fitnessmanager&amp;hl=de\">&#8216;Fitness Manager&#8217; App in the Google Play Store<\/a> or the <a href=\"https:\/\/itunes.apple.com\/us\/app\/fitness-manager\/id447600109?l=de&amp;ls=1&amp;mt=8\">&#8216;Fitness Manager&#8217; App in the iTunes Store<\/a>. See you.<\/p>\n<p align=\"JUSTIFY\"><span style=\"color: #000000;\"><span style=\"font-family: Times New Roman,serif;\"><span style=\"font-size: medium;\">Follow us on<\/span><\/span><\/span><\/p>\n<p><a href=\"https:\/\/www.facebook.com\/Fitness-Manager-106773422758349\">Facebook<\/a><br \/>\n<a href=\"https:\/\/twitter.com\/FitnessManager_\">Twitter<\/a><br \/>\n<a href=\"https:\/\/plus.google.com\/100472904065361948117\">Google Plus<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The &#8216;Fitness Manager&#8217; App provides several statistics for the user in order to check the workout progress. The different statistics should be displayed in a TabHost. A TabHost is a container for a tabbed window view. The TabHost holds two children. One child contains a set of tab labels that the user clicks to select [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[392],"tags":[394,439,444,442,443,420,441,440,395,437,438,404,393,405],"class_list":["post-1481","post","type-post","status-publish","format-standard","hentry","category-android-app-development","tag-android","tag-android-framelayout","tag-android-getchildat","tag-android-gettabcontentview","tag-android-gettabwidget","tag-android-linearlayout","tag-android-onsaveinstancestate","tag-android-setontabchangelistener","tag-android-studio","tag-android-tabhost","tag-android-tabwidget","tag-app","tag-fitness-manager","tag-java"],"_links":{"self":[{"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/posts\/1481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/comments?post=1481"}],"version-history":[{"count":8,"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/posts\/1481\/revisions"}],"predecessor-version":[{"id":1516,"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/posts\/1481\/revisions\/1516"}],"wp:attachment":[{"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/media?parent=1481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/categories?post=1481"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.mplx.de\/Fremdgesteuert\/wp-json\/wp\/v2\/tags?post=1481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}