The scenerio is like this. Currently I am using the following code
TabSpec setContent = tabhost.newTabSpec("tab")
.setIndicator("tabview")
.setContent(new Intent(tabhost.getContext(), someActivity.class));
But I am told that each tab should not be associated with an activity and we must follow code something like this.
TabSpec setContent = tabhost.newTabSpec("tab").setIndicator("tabView").setContent(R.id.layout)
Consider a scenario where tab1 calls camera app, tab2 parses an XML and tab3 does some other display work. How do I solve this ? Because as soon as tab is changed I must call these methods. How do I create a single activity and assign all responsibilities to it ?
You can create a single activity with tabs that show only views. The only catch is that the views have to be defined inside the tag.
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/list1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<ListView
android:id="#+id/list2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</FrameLayout>
Then, when inside your onCreate in your TabActivity:
TabHost tabs = getTabHost();
TabHost.TabSpec commentsTab = tabs.newTabSpec(TAB_TAG_1);
tabs.addTab(commentsTab.setContent(R.id.list1));
TabHost.TabSpec infoTab = tabs.newTabSpec(TAB_TAG_2);
tabs.addTab(infoTab.setContent(R.id.list2));
Note that I did not specify indicators for either tab, in the interests of space.
Related
In my android app main screen has couple of panel. In the first panel consist of two tab, which display the predefine database information as a list view. Problem is when the main screen show the database information it overlay the two tab, basically tab function is not reachable anymore. Is there any way to give line space or clear distinction before textview ? Please see the image file. Thanks for any suggestion or recommendation.
XML code:
<?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"
android:paddingTop="0px" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
</TabHost>
Java Code
super.onCreate(savedInstanceState);
setContentView(R.layout.event_panel);
TabHost tabHost = getTabHost();
TabSpec spec1 = tabHost.newTabSpec("Tab 1");
spec1.setIndicator("Text-1");
Intent in1 = new Intent(this, Tab1.class);
spec1.setContent(in1);
TabSpec spec2 = tabHost.newTabSpec("Tab 2");
spec2.setIndicator("Text-2");
Intent in2 = new Intent(this, Tab2.class);
spec2.setContent(in2);
tabHost.addTab(spec1);
tabHost.addTab(spec2);
tabHost.getTabWidget().getChildAt(0).setLayoutParams(new LinearLayout.LayoutParams(160, 35));
tabHost.getTabWidget().getChildAt(1).setLayoutParams(new LinearLayout.LayoutParams(160, 35));
It seems you set the layout programmaticly try to change the height at this line:
tabHost.getTabWidget().getChildAt(0).setLayoutParams(new LinearLayout.LayoutParams(290, 35));
35 seems to small, pick a higher number that should solve it I guess
There is five EditText widget placed in first tab, five EditText widget placed in second tab and five EditText widget placed in third tab. Now i want to add the data of all the tabs into database by clicking on a single button.
The button is not inside the tab layout. its inside the linear layout...
The xml tree structure is like this:
<?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"
android:background="#ffffff" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="300dp" >
</FrameLayout>
<Button
android:id="#+id/submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
</TabHost>
Yes don't put a button at the end of each activity of the tabcontent. What you do is instead of taking 3 separate Activities don't take any internal sub activities. In your main Activity, Inflate all the layouts(which you are setting as content view for activities) and set them as content for the 3 Tabs. Then you will have 3 Views which are inflated. Now Create the EditTexts object with respect to view perspective and use them when clicked on the button. Hope you understand my Idea. And more importantly it is not suggested to use Activities as contents of Tabs as they consume more memory. I know there are many tutorials which follow the same but hide the drawback.
I have inflated three activity. all all the three activity contains EditTexts. The code is as follows:
TabHost tabHost = getTabHost();
// Tab for Photos
TabSpec photospec = tabHost.newTabSpec("Photos");
photospec.setIndicator("General", getResources().getDrawable(R.drawable.icon_photos_tab));
Intent photosIntent = new Intent(this, PhotosActivity.class);
photospec.setContent(photosIntent);
// Tab for Songs
TabSpec songspec = tabHost.newTabSpec("Songs");
// setting Title and Icon for the Tab
songspec.setIndicator("Private", getResources().getDrawable(R.drawable.icon_songs_tab));
Intent songsIntent = new Intent(this, SongsActivity.class);
songspec.setContent(songsIntent);
// Tab for Videos
TabSpec videospec = tabHost.newTabSpec("Videos");
videospec.setIndicator("Other", getResources().getDrawable(R.drawable.icon_videos_tab));
Intent videosIntent = new Intent(this, VideosActivity.class);
videospec.setContent(videosIntent);
// Adding all TabSpec to TabHost
tabHost.addTab(photospec); // Adding photos tab
tabHost.addTab(songspec); // Adding songs tab
tabHost.addTab(videospec); // Adding videos tab
I have added EditText in all 3 tabs and i want to add the data of all 3 tab(Containing EditText) to database by clicking on a single button. and the button is in main.xml
The output is as bellow:
I'm trying to get a tabbed layout working on android. Using an example I managed to get the tabs working but my different tabs are in different activities. Each tab is similar, it's almost the same so I want them in the same activity.
I want an xml file in the layout folder as content.
This works, seperate classes:
tabSpec1.setIndicator("tabName1").setContent(new Intent(this, FirstTab.class));
This doesn't work:
tabSpec2.setIndicator("tabName2").setContent(R.layout.tab);
The setContent function accepts id's like that. The reference to tab is also in my R class. This is the XML in my tab:
<?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">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This is the tab from XML"/> </LinearLayout>
Check this: unable to add views in TabHost by IDs, crashing
If you want to set content of each tab by View ids, you have to make sure that there is some layout xml that defines TabHost, TabWidget, and FrameLayout tags properly. Then the views that you want to be set by ids can be put as child tags in FrameLayout. Without any one of the tags mentioned above, the app will crash due to "cannot find view id xxxxxx".
You can get what you want by combining this and the <include> tag.
There are a couple of ways to do this. One way is to add a view like Cephron has shown in another answer.
Depending on how similar the tab activities are. Another way to do this would be to pass the intent to the same activity with different extras and then parse them in the Activity code.
Something like:
Intent intent = new Intent(this, FirstTab.class);
intent.putExtra("callingTab", 1);
tabSpec1.setIndicator("tabName1").setContent();
You activity code can then use something like this:
if (FirstTab.this.getIntent().getExtras() != null) {
callingTab = this.getIntent().getExtras().getInt("callingTab");
}
This will allow you to use the same layout for both activities with the minor changes you require coded in.
I think what you need is to have Views, not activities, in each tab. Try something like this...
In the tab activity:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_page_layout);
//Setting up TabWidget
Resources res = getResources();
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
spec = tabHost.newTabSpec("firstTab")
.setIndicator(res.getString(R.string.tab1_label), res.getDrawable(R.drawable.tab1_icon))
.setContent(R.id.tab1_layout);
tabHost.addTab(spec);
spec = tabHost.newTabSpec("secondTab")
.setIndicator(res.getString(R.string.tab2_label), res.getDrawable(R.drawable.tab2_icon))
.setContent(R.id.tab2_layout);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
In the tab_page_layout.xml file:
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:id="#+id/tab1_layout"
/>
<!--your stuff-->
</LinearLayout>
<LinearLayout android:id="#+id/tab2_layout"
/>
<!--your stuff-->
</LinearLayout>
</FrameLayout>
(The above is just a fragment, of course. You'll still need to include the TabWidget and use the appropriate identification)
This is my first tabbed application for Android. I walked through the "HelloTabWidget" app on androids website, but I can't figure out how to add content to the tabs. The FrameLayout stacks stuff on top of each other to the top left (from what I've read). I added a couple of textviews and an imageView, but it only displays the last item added. Is there a way to use Linear Layout instead of Frame Layout? If not, how can you place multiple views in the tab? The only thing I have done different from the example is I added a 4th tab. In one of the tab Activities I inserted the following code to try to get multiple items to display:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("This is the About tab");
setContentView(textview);
TextView textview2 = new TextView(this);
textview2.setText("About Test");
setContentView(textview2);
ImageView imgView = new ImageView(this);
imgView.setImageDrawable(getResources().getDrawable(R.drawable.header));
setContentView(imgView);
}
Here is the link to the example I followed:
http://developer.android.com/resources/tutorials/views/hello-tabwidget.html
What is your layout xml file? I use this and I can stack several textview in every tab. TabActivity:
<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">
<ScrollView android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabWidget android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</ScrollView>
</TabHost>
Activity inside tab:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView android:id="#+id/textOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/textTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout>
I'm a newbie myself, so there might be a better way to do it. This works for me, though.
You didn't read the example carefully. Take a look at the point number 6; you will see something like:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources(); // Resource object to get Drawables
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, ArtistsActivity.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("artists").setIndicator("Artists",
res.getDrawable(R.drawable.ic_tab_artists))
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, AlbumsActivity.class);
spec = tabHost.newTabSpec("albums").setIndicator("Albums",
res.getDrawable(R.drawable.ic_tab_albums))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, SongsActivity.class);
spec = tabHost.newTabSpec("songs").setIndicator("Songs",
res.getDrawable(R.drawable.ic_tab_songs))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(2);
}
That's what you put in the onCreate for the TabActivity. As you can see it has 3 activities. What you are doing is using JUST ONE activity and setting the content view 3 times, which is obviously wrong.
So... how to make it work? First, read again the tutorial. Second, create one activity for each tab you want to show. And use the model above to add those activities to your TabHost.
I am following this tutorial https://developer.android.com/guide/tutorials/views/hello-tabwidget.html and have completed it. Now I would actually like to add you know some controls to these tabs like textboxes(text edit).
How do I do this? I go to my mail.xml using eclipse as my ide and go to layout view and I now get a NullPointerException so I can't even drag stuff onto the layout anymore.
Edit
This is what I have
<?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">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="this is a tab" />
<EditText android:text="" android:id="#+id/EditText01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:password="true"></EditText>
</LinearLayout>
<TextView
android:id="#+id/textview2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="this is another tab" />
<TextView
android:id="#+id/textview3"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="this is a third tab" />
</FrameLayout>
</LinearLayout>
</TabHost>
Tabs are a bit funny to get working initially since there's a lot of code overhead, but once you've worked your way through that they aren't too bad. To get tabs to work, let's start by improving your XML file and then we can make sure your code to actually load them is correct.
First off, your XML file. Instead of including everything directly in your main.xml, you should use the include feature. As the name would suggest, this lets you work on a separate xml file and then include it in your main with one line. This makes the main.xml file much easier to read. So we'd modify your file above to make it look like this:
//No need to change anything above this
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="#layout/tab1"/>
<include layout="#layout/tab2"/>
//and however many other tabs you want to include
</FrameLayout>
You then need to create tab1.xml, tab2.xml and so forth. These are normal xml files in that they start with a ViewGroup (i.e. LinearLayout, RelativeLayout) which contains any number of other widgets. These widgets can be things like EditTexts, buttons, custom views, whatever you want. The only rule is that the parent ViewGroup (the one at the top) must have a unique ID in it, in the manner of android:id="#+id/someUniqueName". You will use that to refer to that specific layout/tab in your code. So for example, this would be:
tab1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tab1Layout"
android:orientation="vertical">
<TextView ... />
<EditText ... />
</LinearLayout>
With that done, we can look at your code. I assume you've probably already got this, but just in case here's what you want:
public class YourProject extends TabActivity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources();
TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("Tab1 title",
res.getDrawable(R.drawable.logo1)).setContent(R.id.tab1Layout));
(...)
//You can also fill tabs with a separate activity like so:
Intent intent = new Intent(this, YourClass.class);
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("Another title",
res.getDrawable(R.drawable.logo2)).setContent(intent));
tabHost.setCurrentTab(0);
}
}
As shown above you can set the content of one of the tabs to be a separate activity. In that case, the activity is defined just as any other one with its own Class, layout, etc. Usually you shouldn't do this and instead just use a different View (with setContent(R.id.tabXLayout), but sometimes it's needed. For example if you want one of your tabs to have a list, then you need to start an activity in there that extends ListView, and include all the boilerplate code for ListViews.
I hope that helps!
The layout view in Eclipse can be a bit flaky, particularly with complex layouts. A bit of trial and error might find the View node it is choking on.
As regards developing the tab-based layout further, you have two options, the 'quick' way or the 'right' way. First is to adapt the existing layout xml by replacing one of the TextViews with a LinearLayout (or some other layout) which contains the content you want.
http://google.com/codesearch/p?hl=en#HQNWZ1u2Pig/trunk/HelloLayoutAndroid/res/layout/tab_widget.xml
However Tabs are generally used where there is complex content. For scalability it may be better to locate the TabHost in the layout, call newTabSpec() and then use setContent() to supply an Intent that identifies an internal Activity, which supplies its own Layout.
the include often makes problems while parsing XML, I tried it and got :cannot resolve #layout/mylayout..
my code was correct 100%, but it's common problem spicialy if you need Id for the layout and other attributes.
samply: I solve it by the disign mode, when you drop tabhost to your layout, place it wherever you want, it creates 3 Linear layouts (tab1,tab2,tab3)... on XML editor, in each tab (leanearlayout) insert your markup of the control you need to use as content of the tab.
and in java file do the next:
TabHost tabHost = (TabHost)findViewById(R.id.tabHost);
tabHost.setup();
TabHost.TabSpec tab1 = tabHost.newTabSpec("smil1");
TabHost.TabSpec tab2 = tabHost.newTabSpec("smil2");
TabHost.TabSpec tab3 = tabHost.newTabSpec("smil3");
tab1.setIndicator("#1");//the name will apear on the first tab
tab1.setContent(R.id.smiles1); // the Id of the control you put in the first LeanerLayout
tab2.setIndicator("#2"); // the same as abouv but for the second tab
tab2.setContent(R.id.smiles2);
tab3.setIndicator("#3"); // the thierd tab
tab3.setContent(R.id.smiles3);
// add the tabs
tabHost.addTab(tab1);
tabHost.addTab(tab2);
tabHost.addTab(tab3);
this is the way solving your problem if include makes problem in parsing your XML.
The NullPointerException in the layout editor is a known bug in the Android Development Tools.