7

I am trying to create tab layout with fragments. When i add another fragment on item click it should show another fragment above it. I am unable to get the goal. Fragment just goes above the existing one but both the fragments content are visible. Please don't throw the link towards any developer page for explanation.

Here is my code

home_activity.xml

<TabHost
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentBottom="true" >

    <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" >
        </TabWidget>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <fragment
                android:id="@+id/tab1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                class="com.example.tabsfragment.School_Fragment" >
            </fragment>

            <fragment
                android:id="@+id/tab2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                class="com.example.tabsfragment.Sports_Fragment" >
            </fragment>
        </FrameLayout>
    </LinearLayout>
</TabHost>

Home_Activity.java

public class Home_Activity extends FragmentActivity {

TabHost mHost;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home_activity);

    mHost = (TabHost) findViewById(android.R.id.tabhost);

    mHost.setup();

    TabSpec schoolSpec = mHost.newTabSpec("School").setIndicator("School")
            .setContent(R.id.tab1);
    mHost.addTab(schoolSpec);

    TabSpec sportSpec = mHost.newTabSpec("Sports").setIndicator("Sportss")
            .setContent(R.id.tab2);
    mHost.addTab(sportSpec);

    mHost.setCurrentTab(1);

}

entertainment.xml

<FrameLayout
    android:id="@+id/frameContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />
</FrameLayout>

I am adding another fragment on list_item_click inside Sports_Fragment

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        // TODO Auto-generated method stub

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        Entertainment_Fragment enFragment = new Entertainment_Fragment();
        ft.replace(android.R.id.tabcontent, enFragment);
        ft.commit();
    }

Here is the snapshot :

Screenshot

Any ideas/help with explanation would be highly appreciated.

Thanks!!

moDev
  • 5,248
  • 4
  • 33
  • 63
  • *I am trying to create tab layout with fragments* - don't. Fragments as tabs are meant to be added at runtime. – user May 23 '13 at 15:10
  • @Luksprog so what's the way to do it?? Any example plz – moDev May 24 '13 at 07:34
  • @droid dev I have implemented custom swipeTabs+viewpager not sherlockActiionBar. If you want then i can post here solution..it's easy to implement.but the thing is that you cannot add fragment dynamically.So it is up to you. – TheFlash May 27 '13 at 06:11
  • @Pratik Above comment indicates that fragment are to be added at a runtime – moDev May 27 '13 at 07:29
  • @droid dev sry i haven't implemented the code you want..! – TheFlash May 27 '13 at 07:31
  • @Pratik no problem. thanks for looking it. – moDev May 27 '13 at 07:33
  • @droid dev 1 thing i want to know have you implemented sherlockActioBar in your app?and i haven't tried it yet.because it's hard to integrate in application..so my question is how is this library..i mean is it working nicely? – TheFlash May 27 '13 at 07:36

1 Answers1

10

First of all, I think it's worth mentioning...

"You cannot replace a fragment defined statically in the layout file. You can only replace fragments that you added dynamically via a FragmentTransaction"

Please see

Android: can't replace one fragment with another

How can I show a new Fragment within a single tab?

Here's the solution.

In home_activity.xml, you should leave your tabcontent empty.

    <FrameLayout
        android:id="@+id/tabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

Your Home_Activity

    private FragmentTabHost mHost;

public void changeFragment() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    EntertainmentFragment enFragment = new EntertainmentFragment();
    ft.replace(R.id.tabcontent, enFragment);
    ft.commit();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
    mHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
    mHost.addTab(mHost.newTabSpec("School")
            .setIndicator("School"), SchoolFragment.class, null);
    mHost.addTab(mHost.newTabSpec("Sport")
            .setIndicator("Sport"), SportsFragment.class, null);
}

In your onIemClick (Sports_Fragment), add this

MainActivity mainAct = (MainActivity)getActivity();
            mainAct.changeFragment();

My full project, which is based on your code, is here.

I haven't had a chance to really check why TabHost doesn't work when I tested your code. But FragmentTabHost works fine for me.

Edit: To fix the overlap problem, you can set OnTabChangeListener:

mHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {

        @Override
        public void onTabChanged(String tabId) {
            // TODO Auto-generated method stub
            if (tabId.equalsIgnoreCase("School")) {
                Log.v(TAG, "school");
                FragmentTransaction ft = getSupportFragmentManager()
                        .beginTransaction();
                schoolFrag = new SchoolFragment();
                ft.replace(R.id.tabcontent, schoolFrag);
                ft.commit();
            }
            if (tabId.equalsIgnoreCase("Sport")) {
                Log.v(TAG, "Sport");
                FragmentTransaction ft = getSupportFragmentManager()
                        .beginTransaction();
                SportsFragment sportFrag = new SportsFragment();
                ft.replace(R.id.tabcontent, sportFrag);
                ft.commit();
            }
        }

    });

About the backpress, you can try

ft.addToBackStack(null);
Community
  • 1
  • 1
pt2121
  • 11,720
  • 8
  • 52
  • 69
  • It's working but when i switch back to another tab, it just overlaps the current fragment on it. – moDev May 28 '13 at 06:29
  • If i have multiple fragments on a tab, then how to come back to previous fragment using backpress?? – moDev May 28 '13 at 06:34
  • It's working.. But its overlaps if i set `mHost.setCurrentTabByTag("Sports");`. Any idea?? – moDev May 29 '13 at 08:53
  • From my understanding, setCurrentTabByTag doesn't provide support for fragment. (You can check the API source code and you'll see). We have to find the work around... – pt2121 May 29 '13 at 14:13
  • Welcome. Sorry that I can't help much. I feel like the ActionBar+Tab API is newer and more flexible. – pt2121 May 30 '13 at 13:41
  • Hi i need help regarding the above question. Currently fragments are getting overlayed when i trying to show another fragment in same layout – moDev Jul 02 '13 at 08:21
  • can you plz help its urgent?? – moDev Jul 02 '13 at 13:57
  • Please have a look at this question http://stackoverflow.com/questions/17429158/fragment-getting-overlapped-on-another-fragment – moDev Jul 02 '13 at 15:07