web-dev-qa-db-de.com

TabHost mit Fragmenten und FragmentActivity

Ich arbeite an einer Android-App und möchte drei Registerkarten für die Navigation verwenden, wobei Fragmente für jede Registerkarte verwendet werden. Ich weiß jedoch nicht, wie ich die Struktur dafür erstellen soll.

Ich möchte jedes Fragment einzeln hinzufügen, da jedes anders ist, aber ich weiß nicht, wo ich es in FragmentActivity hinzufügen soll.

Ich habe diese Dateien.

tabs_layout.xml

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

    <TabHost 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:layout_width="match_parent"
                Android:layout_height="wrap_content"
             />

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

             >

                 <FrameLayout
                     Android:id="@+id/tabRateAPet" 
                     Android:layout_width="match_parent"
                     Android:layout_height="match_parent"

                 />

                 <FrameLayout
                     Android:id="@+id/tabViewMyRates" 
                     Android:layout_width="match_parent"
                     Android:layout_height="match_parent"

                 />

                 <FrameLayout
                     Android:id="@+id/tabViewGlobalRates" 
                     Android:layout_width="match_parent"
                     Android:layout_height="match_parent"

                 />


             </FrameLayout>
        </LinearLayout>
    </TabHost>
</LinearLayout>

TabsMain.Java

import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.support.v4.app.FragmentActivity;

public class MainTabsActivity extends FragmentActivity {
public static final String RATE_A_PET = "Rate a Pet";
public static final String MY_RATES = "My Rates";
public static final String GLOBAL_RATES = "Global Rates";

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabs_layout);
 }
}

Tabs.Java

import Android.app.Activity;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.support.v4.app.FragmentManager;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TabHost;
import Android.widget.TabHost.OnTabChangeListener;
import Android.widget.TabHost.TabSpec;
import Android.widget.TextView;

public class Tabs extends Fragment implements OnTabChangeListener {
    private static final String TAG = "FragmentTabs";
    public static final String RATE_A_PET = "Rate a Pet";
    public static final String MY_RATES = "My Rates";
    public static final String GLOBAL_RATES = "Global Rates";

    private View mRoot;
    private TabHost mTabHost;
    private int mCurrentTab;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
//      super.onCreateView(inflater, container, savedInstanceState);
        mRoot = inflater.inflate(R.layout.tabs_layout, null);
        mTabHost = (TabHost) mRoot.findViewById(Android.R.id.tabhost);
        setupTabs();
        return mRoot;
    }

    private void setupTabs() {
        mTabHost.setup(); // important!
        mTabHost.addTab(newTab(RATE_A_PET, R.string.tabRateAPet, R.id.tabRateAPet));
        mTabHost.addTab(newTab(MY_RATES, R.string.tabViewMyRates, R.id.tabViewMyRates));
    }

    private TabSpec newTab(String tag, int labelId, int tabContentId) {
        Log.d(TAG, "buildTab(): tag=" + tag);

        View indicator = LayoutInflater.from(getActivity()).inflate(
                R.layout.tab,
                (ViewGroup) mRoot.findViewById(Android.R.id.tabs), false);
        ((TextView) indicator.findViewById(R.id.text)).setText(labelId);

        TabSpec tabSpec = mTabHost.newTabSpec(tag);
        tabSpec.setIndicator(indicator);
        tabSpec.setContent(tabContentId);
        return tabSpec;
    }


    @Override
    public void onTabChanged(String tabId) {
        Log.d(TAG, "onTabChanged(): tabId=" + tabId);
        if (RATE_A_PET.equals(tabId)) {
            updateTab(tabId, R.id.tabRateAPet);
            mCurrentTab = 0;
            return;
        }
        if (MY_RATES.equals(tabId)) {
            updateTab(tabId, R.id.tabViewMyRates);
            mCurrentTab = 1;
            return;
        }
        if (GLOBAL_RATES.equals(tabId)) {
            updateTab(tabId, R.id.tabViewGlobalRates);
            mCurrentTab = 2;
            return;
        }
    }   
    private void updateTab(String tabId, int placeholder) {
        FragmentManager fm = getFragmentManager();
        if (fm.findFragmentByTag(tabId) == null) {
            fm.beginTransaction()
                    .replace(placeholder, new RateMyPetActivity(), tabId)
                    .commit();
        }
    }

}
29
imarban

Ich würde vorschlagen, für jede Registerkarte eine separate Fragmentdatei zu erstellen. Das habe ich kürzlich auch getan, daher habe ich meinen Code unten aufgeführt:

Layoutdateien

activity_main.xml 

<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>

tab1_view.xml // füge die entsprechenden Tabulatorlayouts mit diesem Format hinzu (verändere die String-Variablen)

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
        tools:context=".DeviceFragment" >

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="@string/tab1_fragment_string" />

</LinearLayout>

SRC-Dateien

MainActivity.Java // Beachten Sie, dass ich im .addTab-Prozess nur Text verwendet habe. Sie können auch Symbole hinzufügen, indem Sie Zeichensätze verwenden, die Sie Ihrem hdpi-Ordner hinzufügen müssten. Ich habe in diesem Beispiel auch nur drei Registerkarten erstellt.

package com.example.applicationname;

import Android.os.Bundle;
import Android.support.v4.app.FragmentActivity;
import Android.support.v4.app.FragmentTabHost;

public class MainActivity extends FragmentActivity {
    // Fragment TabHost as mTabHost
    private FragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabHost = (FragmentTabHost)findViewById(Android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

        mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"),
            Tab1Fragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab2"),
            Tab2Fragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Tab3"),
            Tab3Fragment.class, null);
    }
}

Tab1Fragment.Java // erneut für die gewünschte Anzahl Tabs replizieren

package com.example.applicationname;

import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;

public class Tab1Fragment extends Fragment  {

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View V = inflater.inflate(R.layout.tab1_view, container, false);

        return V;
    }
}

Stellen Sie sicher, dass Ihre R.Java- und strings.xml-Dateien ordnungsgemäß eingerichtet sind und Ihre Registerkarten aktiviert sind.

78
Kylie Moden

TabHostbehält nicht Fragmente Zustände. Warum also TabHost verwenden?

Verwenden Sie also stattdessen ViewPager mit TabLayout .

Prons of Viewpager über Tabhost:

  • ViewPager behält die Fragmentierungszustände bei. Das mittlere Fragment wird nicht erneut erstellt, wenn gewechselt wird.
  • Integrierte Wischfunktion, die dem Benutzer ein ruhigeres Erlebnis bietet.
  • Weniger CPU-Verbrauch, da Tabhost immer wieder neu erstellt wird, wenn Tab gewechselt wird.

Sieh den Unterschied : 

Tablayout + ViewPager verwenden (Unterstützt Streichen, behält den Status der Fragmente bei

 Tablayout + ViewPager

Verwenden von TabHost (Unterstützt kein Durchblättern, behält Status nicht bei)

 TabHost

Kleiner Code für Tablayout + ViewPager

// find views by id
ViewPager viewPager = findViewById(R.id.viewpager);
TabLayout tabLayout = findViewById(R.id.tablayout);

// attach tablayout with viewpager
tabLayout.setupWithViewPager(viewPager);

ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());

// add your fragments
adapter.addFrag(new SampleFragment(), "Tab1");
adapter.addFrag(new SampleFragment(), "Tab2");
adapter.addFrag(new SampleFragment(), "Tab3");

// set adapter on viewpager
viewPager.setAdapter(adapter);

XML-Layout

<?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">

    <com.google.Android.material.tabs.TabLayout
        Android:id="@+id/tablayout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

    <androidx.viewpager.widget.ViewPager
        Android:id="@+id/viewpager"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1" />

</LinearLayout>

Hinweis Wenn Sie AndroidX noch nicht verwenden, müssen Sie Folgendes im Layout ändern.

  • com.google.Android.material.tabs.TabLayout in Android.support.design.widget.TabLayout ändern
  • Chagne androidx.viewpager.widget.ViewPager zu Android.support.v4.view.ViewPager

Aber ich empfehle dringend, auf AndroidX zu migrieren, siehe @Diese Antwort , um zu verstehen, warum.

Und dies ist allgemeinViewPagerAdapterfür alle Ihr Viewpager in der App.

public class ViewPagerAdapter extends FragmentStatePagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }

    public void addFrag(Fragment fragment) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add("");
    }

    public void addFrag(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }
}

Wichtige verwandte Links

0
Khemraj