The graphical layout for a simple android.support.v4.app.FragmentTabHost never renders in either Eclipse or Android Studio.
The Console error I get is consistently:
Exception raised during rendering: No tab known for tag null
I'm using the most basic XML file:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
but the same error occurs.
I just wanted to add more views above or below the tab widget and frame layout.
I don't care so much about seeing the tab content; I just want to see the rest of my layout - but the problem is that NO OTHER VIEWS are rendered when a android.support.v4.app.FragmentTabHost resides in the layout.
I've read and tried to resolve the issue from the answer to this post:
Android: Tabs at the bottom with FragmentTabHost
but I don't think that that is my problem; I'm not looking to put a TabWidget on the bottom.
Every other one of my XML files opens perfectly.
The same problem occurs in Android Studio:
I had the same rendering problem as well as compilation error. I fixed the problem by finding that I was not passing Fragment when i was creating Addtab. You must pass atleast one fragment on mTabHost.addTab. Below is the working code.
private FragmentTabHost mTabHost;
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(HomeActivity.this, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("home").setIndicator("Home"), HomeFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("mysheets").setIndicator("MySheets"));
mTabHost.addTab(mTabHost.newTabSpec("bookmarks").setIndicator("Bookmarks"));
Not sure about the error you've got (sorry, I'm really busy right now so can't spend more time checking) but in general it seems that the FragmentTabHost from the support libs doesn't care about the xml at all. See my previous answer to another question:
FragmentTabHost with horizontal scroll
From Layout i am getting the same Error..so,I resolve that Problem by Code only...It's working fine..Please try this code
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class DetailFragment extends Fragment {
/******************************************************************************************************************
* Mandatory empty constructor for the fragment manager to instantiate the fragment (e.g. upon screen orientation changes).
*****************************************************************************************************************/
public DetailFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// R.layout.fragment_tabs_pager contains the layout as specified in your question
View rootView = inflater.inflate(R.layout.fragment_tabs_pager, container, false);
// Initialise the tab-host
FragmentTabHost mTabHost = (FragmentTabHost) rootView.findViewById(R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
// Initialise this list somewhere with the content that should be displayed
List<String> itemsToBeDisplayed;
for (String subItem : itemsToBeDisplayed) {
// Give along the name - you can use this to hand over an ID for example
Bundle b = new Bundle();
b.putString("TAB_ITEM_NAME", subItem);
// Add a tab to the tabHost
mTabHost.addTab(mTabHost.newTabSpec(subItem).setIndicator(subItem), YourContentFragment.class, b);
}
return rootView;
}
}
/********************************************************
This class contains the actual content of a single tab
**********************************************************/
public class YourContentFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getArguments();
if (extras != null) {
if (extras.containsKey("TAB_ITEM_NAME")) {
String subItem = extras.getString("TAB_ITEM_NAME");
// Do something with that string
}
}
}
}
If U need to put fragmented tabs at bottom of screen ...
#fallow undermentioned --
Make your xml file like this ..
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- <RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"> android:layout_alignParentTop="true" -->
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dip"
android:layout_height="0dip"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
Now if your concern is opening several fragments with in single fragmented tabs ...
#follow steps ::
Create a container fragment. This container fragment will be default for all of your's tabs content.
For every tab content replace fragment U need with this container.
For ex:- Just like you replace your bed with different bed sheets .. :)
Your container fragment class that will be used differently in different tabs ... "LearnContainerFragment.java "
public class LearnContainerFragment extends BaseContainerFragment {
private boolean mIsViewInited;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.e("test", "tab 1 oncreateview");
return inflater.inflate(R.layout.container_fragment, null);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.e("test", "tab 1 container on activity created");
if (!mIsViewInited) {
mIsViewInited = true;
initView();
}
}
private void initView() {
Log.e("test", "tab 1 init view");
replaceFragment(new Learn(), false);
}
}
LearnContainerFragment.java --- > it's xml file container_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
# How to use Conatiner..
For every fragment U need will be replaced with id of this container fragment.
#last your BaseContainerFragment.java class --
public class BaseContainerFragment extends Fragment {
public void replaceFragment(Fragment fragment, boolean addToBackStack) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.replace(R.id.container_framelayout, fragment);
transaction.commit();
getChildFragmentManager().executePendingTransactions();
}
public boolean popFragment() {
Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
boolean isPop = false;
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getChildFragmentManager().popBackStack();
}
return isPop;
}
}
Hope it helps.....
Cheers!
not sure.... but shouldn't your layout have a tabhost tag in it above the tabwidget's linear layout?
<TabHost
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
>
i made an app a while back that implented tabs using tabhost and this is how my layout was...one tab had a calendar view one had an image switcher and one had a listview...sorry i can't be of more help
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
tools:context=".MainActivity" >
<TabHost
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
<LinearLayout
android:id="#+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageSwitcher
android:id="#+id/imageSwitcher1"
android:layout_width="match_parent"
android:layout_height="251dp" >
</ImageSwitcher>
<TextView
android:id="#+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</LinearLayout>
<LinearLayout
android:id="#+id/tab3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<CalendarView
android:id="#+id/calendarView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
Related
I noticed that onCreateView() of one of my fragments is never called and i dont know why.I need to be able to make changes in onResume() but thats is also never called.
Here is how I add the fragments.
public class LiveGameStats extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_game_stats);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.tab1, new Tab1Fragment()).commit();
}
FragmentTabHost mTabHost = (FragmentTabHost) findViewById(R.id.liveGameTabhost);
mTabHost.setup(LiveGameStats.this, getSupportFragmentManager(), R.id.liverealtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("You"),
LiveGameTab1Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Your Team"),
LiveGameTab2Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Your Enemies"),
LiveGameTab3Fragment.class, null);
}
Tab1Fragment
public class Tab1Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.tab1, container, false);
Log.v("FRAGMENT","FragmentActivityCreateView");
return V;
}
And finnaly the xml passed under R.layout.tab1
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".DeviceFragment" >
<ImageButton
android:id="#+id/searchBtn"
android:src="#drawable/waves"
android:background="#drawable/search_selector"
android:padding="40dp"
android:layout_height="200dp"
android:layout_width="200dp"
android:onClick="liveMatch"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
I think I might have created the fragments the wrong way. As you see it now they are created as the xml says but when I changed tabs, the content is "reseted".Any changed I placed in onCreateView() or onResume() is not called.
EDIT
I have tried to implement the method described in the 1st comment. After the implementation the tabs have the same content. Is like all the tabs have the same content. This time I posted all my classes and their associated XML.
public class LiveGameStats extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_game_stats);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent, new LiveGameTab1Fragment()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent, new LiveGameTab2Fragment()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent, new LiveGameTab3Fragment()).commit();
}
FragmentTabHost mTabHost = (FragmentTabHost) findViewById(R.id.liveGameTabhost);
mTabHost.setup(LiveGameStats.this, getSupportFragmentManager(), R.id.liverealtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("You"),
LiveGameTab1Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Your Team"),
LiveGameTab2Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Your Enemies"),
LiveGameTab3Fragment.class, null);
}
activity_live_game_stats.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_live_game_stats"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light"
tools:context="lucian.leagueassistant.activity.LiveGameStats">
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/liveGameTabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+id/liverealtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
I wont post the code from LiveGameTab2 and LiveGameTab3 since they are almost the same. I have also another activity that
Edit2
Seems its solved when i changed from getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent, new LiveGameTab1Fragment()).commit(); to getSupportFragmentManager().beginTransaction().add(android.R.id.tabcontent, new LiveGameTab1Fragment()).commit();
The problem is this:
getSupportFragmentManager().beginTransaction().add(R.id.tab1, new Tab1Fragment()).commit();
In the first argument you have to pass a id to a container in the Activity layout where your fragment will be attached.
You are passing a entire layout R.id.tab1.
Add a container view in activity_live_game_stats xml file,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".DeviceFragment" >
<FrameLayout
android:id="#+id/myContainer"
...(Other attrs)>
</FrameLayout>
</RelativeLayout>
and then
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.myContainer, new Tab1Fragment()).commit();
}
I am trying to create a set of vertical tabs within an android project, I have been looking at a number of tutorials and posts on SO but cannot seem to piece it all together.
I created a new project with a fragment so I have a main.xml and a fragment_main.xml, a main activity class and a mainfragment class.
main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/fragment"
android:name="com.example.android.MainScreenActivityFragment"
tools:layout="#layout/fragment_main" android:layout_width="match_parent"
android:layout_height="match_parent" />
fragment_main.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="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:layout_width="0dip"
android:layout_height="fill_parent" android:layout_weight="0.2">
<TabWidget android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<LinearLayout
android:id="#+id/tab_btn_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button android:layout_height="0dip"
android:layout_width="fill_parent"
android:layout_weight="1.0"
android:background="#color/sunshine_blue"
android:id="#+id/patient_tab_btn"
android:onClick="tabHandler"/>
<Button android:layout_height="0dip"
android:layout_width="fill_parent"
android:layout_weight="1.0"
android:background="#color/sunshine_blue"
android:id="#+id/relations_tab_btn"
android:onClick="tabHandler"/>
<Button android:layout_height="0dip"
android:layout_width="fill_parent"
android:layout_weight="1.0"
android:background="#color/sunshine_blue"
android:id="#+id/providers_tab_btn"
android:onClick="tabHandler"/>
</LinearLayout>
</FrameLayout>
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="0dip"
android:layout_height="fill_parent" android:layout_weight="0.8"/>
</LinearLayout>
The main activity doesnt do anything other than the defaults and I havent added to it as I thought I should use a fragment as the google sunshine app uses a fragment for the main screen.
main fragment class
private FragmentTabHost mTabHost;
Button patientButton, relationsButton, providersButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.tab_btn_container);
patientButton = (Button)rootView.findViewById(R.id.patient_tab_btn);
relationsButton = (Button)rootView.findViewById(R.id.relations_tab_btn);
providersButton = (Button)rootView.findViewById(R.id.providers_tab_btn);
return rootView;
}
public void tabHandler(View target){
Log.d(LOG_TAG, "Calling tabHandler() method");
patientButton.setSelected(false);
relationsButton.setSelected(false);
providersButton.setSelected(false);
if(target.getId() == R.id.patient_tab_btn){
//mTabHost.setCurrentTab(0);
patientButton.setSelected(true);
} else if(target.getId() == R.id.relations_tab_btn){
//mTabHost.setCurrentTab(1);
relationsButton.setSelected(true);
} else if(target.getId() == R.id.providers_tab_btn){
//mTabHost.setCurrentTab(2);
providersButton.setSelected(true);
}
}
So I have added the tabHandler button and the xml is inflated inside the fragment main class but I get an error pressing any of the tab buttons:
java.lang.IllegalStateException: Could not find method tabHandler(View) in a parent or ancestor Context for android:onClick attribute
I am also not sure how I would update the tabcontent pane as all the examples seem to use an Activity and have the activity class extend from TabActivity but using a fragment my class already extends Fragment.
How do I get this to work with a fragment which contains the tabs?
The method that you've specified in android:onClick (tabHandler) should be located in the Activity, not the Fragment. This SO answer has more information: https://stackoverflow.com/a/4153842/3214339
im trying to set up a FragmentTabHost with 3 tabs. The problem im having is the content of each tab is actually being displayed in the tab tittle as well. Why is this happening? The layout for tab1 has a textview that says "Tab1" this is being displayed in the tab and not the content area. also if i change the background it changes the background of the tabs not the content area.
xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
MAIN Fragment:
public class NewFragment _Frag extends Fragment{
private FragmentTabHost mTabHost;
Intent intent;
boolean created = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
//return super.onCreateView(inflater, container, savedInstanceState);
if(container==null)
{
return null;
}
View v = inflater.inflate(R.layout.mylayout, container, false);
mTabHost = (FragmentTabHost)v.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("fragmentb").setIndicator("Tab1"),
myclass1.class, null);
mTabHost.addTab(mTabHost.newTabSpec("fragmentc").setIndicator("Tab2"),
myclass2.class, null);
mTabHost.addTab(mTabHost.newTabSpec("fragmentd").setIndicator("Tab3"),
myclass3.class, null);
return v;
}
First, lets assume your XML name is my_xml.xml.
So make following changes in the my_xml.xml first(Change the ID)
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
and then following changes in the java file.
mTabHost = (FragmentTabHost)v.findViewById(R.id.my_tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.layout.my_xml);
you missed these two :
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
so add them in your Linearlayout above framelayout
actually you do not need any changes because your code is exactly like demo see below:
https://chromium.googlesource.com/android_tools/+/18728e9dd5dd66d4f5edf1b792e77e2b544a1cb0/sdk/extras/android/support/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.java
https://chromium.googlesource.com/android_tools/+/18728e9dd5dd66d4f5edf1b792e77e2b544a1cb0/sdk/extras/android/support/samples/Support4Demos/res/layout/fragment_tabs.xml
I've been experimenting with tab navigation on android but I can't set up the content area correctly.
The layout of the application:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabhost"
android:tag="tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:tag="linear">
<TabWidget
android:id="#+id/tabs"
android:tag="tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</TabWidget>
<FrameLayout
android:id="#+id/tabFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
</android.support.v4.app.FragmentTabHost>
The fragment:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/info_drawer_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e0e0e0">
<FrameLayout
android:id="#+id/info_content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment info"
android:id="#+id/info_textView"
android:layout_gravity="center_horizontal" />
</FrameLayout>
<ListView android:id="#+id/info_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
And the code I used in the activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (FragmentTabHost)findViewById(R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.tabFrameLayout);
tabHost.addTab(tabHost.newTabSpec("Tab 0").setIndicator("", getResources().getDrawable(R.drawable.ic_launcher)), InfoFragment.class, null);
tabHost.addTab(tabHost.newTabSpec("Tab 1").setIndicator("Tab 1"), HomeFragment.class, null);
tabHost.addTab(tabHost.newTabSpec("Tab 2").setIndicator("", getResources().getDrawable(R.drawable.ic_launcher)), AppsFragment.class, null);
}
This generates the following result:
As you can see the content area overlaps the tabs. I would simply like it to be below them and fill up the remaining space like this:
I've tried wrapping them in a RelativeLayout tag and applying the below attribute but it didn't work. I trid using the weight attribute without any luck as well.
Thanks.
You don't need to have the FrameLayout inside the Tabhost, when you do that you're using the same space for the content of the fragments and the tabs themselves.
Just put the TabHost inside a vertical LinearLayout and put the FrameLayout outside, below the TabHost.
Just like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"/>
</android.support.v4.app.FragmentTabHost>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Sorry, i cannot go into detail with your specific code, but if you anyway just try to implement it for the first time i would go this approach, its really easy to understand and to manage. The code is pretty easy and serves all you need i think.
You just have to make own layoutfiles for the 3 (or whatever) fragments like this:
Layoutfile for a Fragment:
<?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"
android:layout_margin="15sp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Notebook"
android:id="#+id/tv_hdl_tab3"
android:textColor="#android:color/holo_blue_light"
android:textSize="#dimen/dim_hdl_h1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/tab3_introText"
android:id="#+id/tv_tab3_IntroText"
android:layout_marginTop="5sp"
android:layout_marginBottom="5sp"
android:textSize="#dimen/dim_txt_p" />
MainActivity:
public class MainActivity extends Activity {
ActionBar.Tab tab1, tab2, tab3;
Fragment fragmentTab1 = new FragmentTab1();
Fragment fragmentTab2 = new FragmentTab2();
Fragment fragmentTab3 = new FragmentTab3();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_test);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tab1 = actionBar.newTab().setText("Home");
tab2 = actionBar.newTab().setText("Calculator");
tab3 = actionBar.newTab().setText("Notebook");
tab1.setTabListener(new MyTabListener(fragmentTab1));
tab2.setTabListener(new MyTabListener(fragmentTab2));
tab3.setTabListener(new MyTabListener(fragmentTab3));
actionBar.addTab(tab1);
actionBar.addTab(tab2);
actionBar.addTab(tab3);
}
And a fragment looks like this then (3 of them of course, one for every tab as long it should be different):
public class FragmentTab3 extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.tab3, container, false);
TextView textview = (TextView) view.findViewById(R.id.tabtextview);
textview.setText(R.string.Three);
return view;
}
}
And the Tablistener:
public class MyTabListener implements ActionBar.TabListener {
Fragment fragment;
public MyTabListener(Fragment fragment) {
this.fragment = fragment;
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// nothing done here
}
}
Code comes from http://www.linux.com/learn/tutorials/761642-android-app-development-for-beginners-navigation-with-tabs
Hello I am having difficulty changing the visual view of the fragment activity. I created all the tabs but onClick I do not know how to pass the activity into that white space.
so the structure of this is a simple activity named Main which just sets the content view to a maintabholder.xml document that holds the fragment view which connects to a class named MainNav whose content view contains all the tabs at the bottom.
maintabholder.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<include layout="#layout/header" android:layout_alignParentTop="true" android:id="#+id/headerArea"></include>
<fragment
class="my.package.name.MainNav"
android:id="#+id/fragment_tabs"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
MainNav.java code snippet:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
mRoot = inflater.inflate(R.layout.fragment_tabs, null);
mTabHost = (TabHost) mRoot.findViewById(android.R.id.tabhost);
setupTabs();
return mRoot;
}
and R.layout.fragment_tabs:
<?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="#EFEFEF">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
android:background="#drawable/tab_background"
android:gravity="center_horizontal"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/tab_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/tab_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/tab_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/tab_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/tab_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
</RelativeLayout>
and Finally the contents of an Activity that I want to load into the Fragment (upon pressing the tab1 button)
public class HomeFragment extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
}
}
That is to help you get the gist of things, but the problem occurs here in MainNav.java:
#Override
public void onTabChanged(String tabId) {
Log.d(TAG, "onTabChanged(): tabId=" + tabId);
if (TAB_HOME.equals(tabId)) {
updateTab(tabId, R.id.tab_1);
mCurrentTab = 0;
return;
}
}
when a tab is clicked, it is registered in the onTabChanged activity, and the updateTab function is called:
private void updateTab(String tabId, int placeholder) {
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag(tabId) == null) {
//fm.beginTransaction()
// .replace(placeholder, /*need fragment object here*/ , tabId)
// .commit();
//
}
}
the commented out replace method is looking for an (int, fragment, string) and I guess it should then change the white space for me.
but I don't understand where I get the fragment object from! This phantom object needs to somehow contain my HomeFragment's xml layout and allow me to interact with everything else I've coded for the HomeFragment activity.
My first hunch is that my HomeFragment activity needs to extend FragmentActivity instead
just activity. But this is where I am hitting a wall.
There is very little documentation on the compatibility pack methods, but the documentation for TabActivity says not to use TabActivity anymore, so here I am. Developing for Android 2.2+
Insight appreciated.
You can't put Activities into Fragments, it's jut that simple. You have to convert your Activities that serve the tab-contents into Fragments. It shouldn't be a problem, given that you don't use fragments in those Activities.
So here are 2 rules to follow:
You can't put Activities into Fragments.
You can't put Fragments into Fragments.
I recommend that you keep that bottom fragment on your layout around just to handle the tab-switches in the tab-widget. If a tab switch happens, you report this to the parent Activity, which will load the corresponding Fragment into the are above the tab-fragment. For this to work, you'd have to modify you layout so it has a ViewGroup above the tab-fragment and below the header. You'd dynamically load the fragments with the tab-contents into that ViewGroup.
Here's the layout (maintabholder.xml):
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<include layout="#layout/header" android:layout_alignParentTop="true" android:id="#+id/headerArea"></include>
<FrameLayout android:id="#+id/TabContent"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
<fragment
class="my.package.name.MainNav"
android:id="#+id/fragment_tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
When a tab-switch happens in your bottom fragment, you tell this to the parent Activity:
...
(YourActivity)getActivity().switchToTab(tabId);
...
And in the YourActivity:
...
public void switchToTab(int tabId){
switch(tabId){
...
case 2:
getSupportFragmentManager().beginTransaction().replace(R.id.TabContent, TabContentFragment2.newInstance(), "someTag").commit().
break;
...
}
}
Something like that.