Creating an Android app using TabHost and multiple fragments

时间秒杀一切 提交于 2019-12-08 12:41:55

问题


I have been trying to create a basic Android app that contains tabs, which when clicked will load a new fragment - each fragment being a separate xml file. I would like to use TabHost and not the Activity Bar tabs. I have been looking through many tutorials on the web and posts here on stackoverflow, but to no avail. Most questions and tutorials are discussing either fragments OR tabs, but not both subjects. Thank you in advance for the suggestions.

I would like to try a very basic app that contains:

  • one fragment to input a number - xml file_1 (1st tab)
  • one fragment to display the number in a TextView - xml file_2 (2nd tab)

回答1:


try like this

your xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >


            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1" >

                <FrameLayout
                    android:id="@+id/tab_1"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" />
            </FrameLayout>

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="0dip"
                android:layout_marginRight="0dip"
                android:layout_weight="0" />
        </LinearLayout>
    </TabHost>

</LinearLayout>

In your activity onCreate

mTabHost = (TabHost)findViewById(android.R.id.tabhost);
        mTabHost.setOnTabChangedListener(this);
        mTabHost.setCurrentTab(0);
        setupTabs();

setupTabs() method

private void setupTabs() {
        mTabHost.setup();
        setupTab(new TextView(this), "Tab1");
        setupTab(new TextView(this), "Tab2");
            setupTab(new TextView(this), "Tab3");
        mTabHost.getTabWidget().setDividerDrawable(R.drawable.empty);//not necessery

    }

setupTab() method //setup a single tab

private void setupTab(final View view, final String tag) {
        View tabview = createTabView(mTabHost.getContext(), tag);

        TabSpec setContent = mTabHost.newTabSpec(tag).setIndicator(tabview).setContent(new TabContentFactory() {
            public View createTabContent(String tag) {
                return view;
            }
        });
        mTabHost.addTab(setContent);

    }

createTabView method

private static View createTabView(final Context context, final String text) {
        int resouceId = R.layout.tabs_bg;
        if(text.equals("Tab1")) {
            resouceId = R.layout.tab_1_layout;
        } else if(text.equals("Tab2")) {
            resouceId = R.layout.tab_2_layout;
        }
        View view = LayoutInflater.from(context).inflate(resouceId, null);
        return view;
    }

onTabChanged method

@Override
    public void onTabChanged(String tabId) {
        Log.d("TAB_CHANGE","onTabChanged(): tabId=" + tabId);
        updateTab(tabId, R.id.tab_1,new YourFragment());
    }

public void updateTab(String tabId, int placeholder,Fragment fragment) {
        FragmentManager fm = getSupportFragmentManager();
        fm.beginTransaction()
        .replace(placeholder,fragment, tabId)
        .commit();
    }



回答2:


First off, thanks to deniz for getting me close enough to the right solution I could eke out a working project. Now, this should be closer to functional. I changed names to be generic, but hopefully everything will work as intended and be enough to help you understand what's happening.

TabHostActivity (your main Activity):

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TabHost;
import android.widget.TextView;

public class TabHostActivity extends FragmentActivity implements TabHost.OnTabChangeListener
{
    private static final String TAG = "TabHostActivity";

    private TabHost tabHost;

    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_tabhost);

        tabHost = (TabHost) findViewById(android.R.id.tabhost);
        tabHost.setOnTabChangedListener(this);
        tabHost.setCurrentTab(0);
        setupTabs();
    }

    private void setupTabs()
    {
        tabHost.setup();
        setupTab(new TextView(this), "tab1");
        setupTab(new TextView(this), "tab2");
        setupTab(new TextView(this), "tab3");
        setupTab(new TextView(this), "tab4");
    }

    private void setupTab(final View view, final String tag)
    {
        View tabview = createTabView(tabHost.getContext(), tag);

        TabHost.TabSpec setContent = tabHost.newTabSpec(tag)
                .setIndicator(tabview)
                .setContent(new TabHost.TabContentFactory()
                {
                    public View createTabContent(String tag)
                    {
                        return view;
                    }
                });
        tabHost.addTab(setContent);
    }

    /**
     * Return the view for the individual tabs, the tab view being set is identified by tabId.
     *
     * @param context
     * @param tabId
     * @return
     */
    private static View createTabView(final Context context, final String tabId)
    {
        int resourceId;
        if (tabId.equals("tab1"))
        {
            resourceId = R.layout.tab1;
        }
        else if (tabId.equals("tab2"))
        {
            resourceId = R.layout.tab2;
        }
        else if (tabId.equals("tab3"))
        {
            resourceId = R.layout.tab3;
        }
        else
        {
            resourceId = R.layout.tab4;
        }

        return LayoutInflater.from(context).inflate(resourceId, null);
    }

    @Override
    public void onTabChanged(String tabId)
    {
        Log.d(TAG, "onTabChanged(): tabId=" + tabId);

        if (tabId.equalsIgnoreCase("tab1"))
        {
            updateTab(android.R.id.tabcontent, new tab1(), tabId);
        }
        else if (tabId.equalsIgnoreCase("tab2"))
        {
            updateTab(android.R.id.tabcontent, new tab2(), tabId);
        }
        else if (tabId.equalsIgnoreCase("tab3"))
        {
            updateTab(android.R.id.tabcontent, new tab3(), tabId);
        }
        else
        {
            updateTab(android.R.id.tabcontent, new tab4(), tabId);
        }
    }

    public void updateTab(int placeholder, Fragment fragment, String tabId)
    {
        getSupportFragmentManager().beginTransaction()
                .replace(placeholder, fragment, tabId)
                .commit();
    }
}

activity_tabhost.xml:

  <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:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >


            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1" >

                <FrameLayout
                    android:id="@+id/tab_1"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" />

                <FrameLayout
                    android:id="@+id/tab_2"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" />

                <FrameLayout
                    android:id="@+id/tab_3"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" />

                <FrameLayout
                    android:id="@+id/tab_4"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" />

            </FrameLayout >

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1" />

        </LinearLayout >

    </TabHost >

tab1.xml, tab2.xml, tab3.xml, tab4.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</LinearLayout>

tab1.java, tab2.java, tab3.java, tab4.java:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class tab1 extends Fragment
{
    private static final String TAG = "tab1";

    @Override
    public void onActivityCreated(final Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        Log.i(TAG, "onActivityCreated");
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
    {
        Log.i(TAG, "onCreateView");

        return inflater.inflate(R.layout.tab1, container, false);
    }
}

AndroidManifest.xml:

<activity android:name="<YOUR_PACKAGE_NAME>.TabHostActivity" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity>

This was done using v19 of the API as target, and with a minimum of v10 using the android.support.v4.app library.

So again, thank you deniz for getting me to this point, I had spent 10 hours trying things and everything I found was out of date. Hopefully this can help other people who are in my ex-state of limbo. You should now have a working state and can see where you can design the tabs as well as where you put the contents of the Fragments.

PS - yes, in my generalization pass it did result in the xml content and the tabs being called "tab1.whatever", hopefully this isn't too confusing, which is which can be deduced with a little context.



来源:https://stackoverflow.com/questions/21474623/creating-an-android-app-using-tabhost-and-multiple-fragments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!