I am designing tabs in my app. I am confused whether to use activities for tab or just use views
which one is the better way for tablayout
I am confused ..
I am bit new to tabs and still learning tab layout in android, so my question can be a little naive so please bear with it :)
To answer your question of "activity or view in a tab layout"
This is what the android tutorial sais:
You can implement your tab content in one of two ways: use the tabs
to swap Views within the same Activity, or use the tabs to change
between entirely separate activities. Which method you want for your
application will depend on your demands, but if each tab provides a
distinct user activity, then it probably makes sense to use a separate
Activity for each tab, so that you can better manage the application
in discrete groups, rather than one massive application and layout.
Android tablayout tutorial
I highly recommend following the tutorial, then try to implement your own version for your app.
Here is a code sample just in case;
public class TabHostExample extends TabActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testtabs);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent content;
spec = tabHost.newTabSpec("test1"); //set a title for the tab
spec.setIndicator("test1"),
getResources().getDrawable(R.drawable.ic_dialog_alert)); //set an icon for tab
content = new Intent(this, ExampleActivityOne.class);
spec.setContent(content);
tabHost.addTab(spec);
spec = tabHost.newTabSpec("test2")); //set a title for the tab
spec.setIndicator("test2"),
getResources().getDrawable(R.drawable.ic_dialog_info)); //set an icon for the tab
content = new Intent(this, ExampleActivityTwo.class);
spec.setContent(content);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
}
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/tabhost">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#android:id/tabs"
/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#android:id/tabcontent"
/>
</LinearLayout>
</TabHost>
A bit of extra information from the tutorial:
The framelayout is where the content of the activity per tab goes.
Notice that the TabWidget and the FrameLayout elements have the IDs tabs and tabcontent, respectively. These names must be used so that the TabHost can retrieve references to each of them. It expects exactly these names.
So with this code you have a basic setup for a tab layout, what you do next is, attach an activity to a tab. You use the activity like normal, for these activities you extend Activity as you normally would for an activity and build your layout in onCreate/onResume
If you need more information or more explanation please leave a comment. I think most code is self explanatory though.
I just noticed my code is almost an exact copy from the tutorial page.
I actually use this code in my app, with different names for the activities etc. It works great. I recommend it. Credits goes to the Android team.
You have to use activities. Every tab has activity. There are good tutorials at developer.android.com Try this one here
Try Activities..Look for TabActivity which is best way to deal the TABS in an App.. http://developer.android.com/reference/android/app/TabActivity.html and http://developer.android.com/resources/tutorials/views/hello-tabwidget.html
Related
I want to implement a tabbed view pager where the tabs are not part of the action bar.
What is the correct way of doing this since it doesn't seem supported by standard.
So far I have been using the following approach and it seems like it's been so much more effort than it should be that it bothers me:
Create horizontally oriented linear layout to act as tab bar view
Create individual tab views to populate tab bar along with styling
Create custom ongesturelistener for left and right swipe to go between tabs
Create animations for sliding-in/out upon swiping (fragment transactions)
Create animations for the tab bar upon swiping
This seems like it's way too much work when there is a viewpager and tabbar built in. It seems though this "proper" approach is limited to only being used in conjunction with the actionbar. Can anyone provide a simple example of what I am trying to achieve? (see following picture for clarity).
You don't need to build a ViewPager bundled with an ActionBar, they are both independent views.
You can simply hide the ActionBar on that activity doing something like:
ActionBar mActionBar = activity.getActionBar();
mActionBar.hide();
Although it's an ugly solution you can do that to test your code. I would suggest either add a Theme to that specific Activity without an ActionBar (something like Theme.Material.NoActionBar) - not sure it's the correct name of the theme, but you get the idea.
Not sure I answered your question accordingly, but if not please show us some code.
You just add a viewpager with a pager tab strip. Plenty examples out there.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getSupportFragmentManager();
fragmentPagerAdapter = new MyTabsPagerAdapter(
fm, tabsArray);
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(fragmentPagerAdapter);
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/default_screen_bg"
android:minWidth="1000dp">
put your image here
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</android.support.v4.view.ViewPager>
I followed this tutorial to created a tab activity using fragments:
http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/
One of the tabbed activities includes a list view; when you click on an item in the list view, it opens a new activity. But I want the new activity to still show the tabs that are in the tab activity. In other words, I want the tabs to show up on all the activities in the application, but I don't know how to make it persistent.
Would someone be able to point me in the right direction?
To make your application persistent, make use of Inheritance. create listView.xml, tabactivity.xml and embed those in MainActivity.xml as below:
<LinearLayout ... >
<include layout="#layout/listView" /> // your listview.xml file will be called
<include layout="#layout/tabactivity" /> // your tabactivity.xml file will be called
</LinearLayout>
You can add your tabview dynamically on every activity start.
In the demo Support4Demos - API 4+ Support Demos , the Tabs and TabsPager examples both extend FragmentActivity. Each tab content is itself a Fragment. No real breakthrough, TabActivity was used the same way without the introduction of Fragment.
Now suppose inside my Activity , a screen portion is a Fragment named WidgetFragment. How is it possible for WidgetFragment to contain a TabHost ? Visualize a mini TabHost contained inside an Activity.
I tried every possible way to insert a TabHost inside a Fragment not a FragmentActivity.
In generally accepted practices, Tabs fit the whole screen.
Most people (including me) are unaware the tabs can be placed anywhere like a simple view, ListView.
The trick is to include your TabHost inside another layout. When you create the TabHost, always keep these id : tabhost , tabs , tabcontent
In your main layout, include your tabhost.xml . Here I center the TabHost in the middle
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- Fill whatever you need -->
<FrameLayout
android:id="#+id/widget_fragment"
android:layout_centerVertical="true" android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<include layout="#layout/tabhost" />
</FrameLayout>
</LinearLayout>
Look well at the Tabs and TabsPager examples in Support4Demos , the TabHost is still managed by FragmentActivity. Each tab content is a fragment. With TabActivity, it may not be possible to have a tab anywhere
At the end, this is what it looks like
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)
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.