Android: pestañas en la parte inferior con FragmentTabHost

Estoy tratando de poner un FragmentTabHost en la parte inferior de la pantalla. Hace tiempo, pude hacer eso con TabHost regular (siguiendo este hilo ), pero ahora esto no está funcionando para mí.

¿Hay una manera de hacer eso?

¡Gracias!

3 Solutions collect form web for “Android: pestañas en la parte inferior con FragmentTabHost”

Finalmente llegué al fondo de esto. Hay un problema con FragmentTabHost.java que siempre creará un elemento TabHost para usted, no importa lo que defina en XML e inflar de antemano.

Como tal, comenté esa parte del código al escribir mi propia versión de FragmentTabHost.java.

Asegúrese de utilizar su nueva versión de este en su diseño XML, <com.example.app.MyFragmentTabHost

Y por supuesto inflarlo:

Fragment1.java:

 mTabHost = (MyFragmentTabHost) view.findViewById(android.R.id.tabhost); mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent); 

MyFragmentTabHost.java:

 package com.example.app; import java.util.ArrayList; import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.util.AttributeSet; import android.view.View; import android.widget.FrameLayout; import android.widget.TabHost; /** * Special TabHost that allows the use of {@link Fragment} objects for * its tab content. When placing this in a view hierarchy, after inflating * the hierarchy you must call {@link #setup(Context, FragmentManager, int)} * to complete the initialization of the tab host. * */ public class MyFragmentTabHost extends TabHost implements TabHost.OnTabChangeListener { private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); private FrameLayout mRealTabContent; private Context mContext; private FragmentManager mFragmentManager; private int mContainerId; private TabHost.OnTabChangeListener mOnTabChangeListener; private TabInfo mLastTab; private boolean mAttached; static final class TabInfo { private final String tag; private final Class<?> clss; private final Bundle args; private Fragment fragment; TabInfo(String _tag, Class<?> _class, Bundle _args) { tag = _tag; clss = _class; args = _args; } } static class DummyTabFactory implements TabHost.TabContentFactory { private final Context mContext; public DummyTabFactory(Context context) { mContext = context; } @Override public View createTabContent(String tag) { View v = new View(mContext); v.setMinimumWidth(0); v.setMinimumHeight(0); return v; } } static class SavedState extends BaseSavedState { String curTab; SavedState(Parcelable superState) { super(superState); } private SavedState(Parcel in) { super(in); curTab = in.readString(); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeString(curTab); } @Override public String toString() { return "FragmentTabHost.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " curTab=" + curTab + "}"; } public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; } public MyFragmentTabHost(Context context) { // Note that we call through to the version that takes an AttributeSet, // because the simple Context construct can result in a broken object! super(context, null); initFragmentTabHost(context, null); } public MyFragmentTabHost(Context context, AttributeSet attrs) { super(context, attrs); initFragmentTabHost(context, attrs); } private void initFragmentTabHost(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.inflatedId }, 0, 0); mContainerId = a.getResourceId(0, 0); a.recycle(); super.setOnTabChangedListener(this); /*** REMOVE THE REST OF THIS FUNCTION ***/ /*** findViewById(android.R.id.tabs) IS NULL EVERY TIME ***/ } /** * @deprecated Don't call the original TabHost setup, you must instead * call {@link #setup(Context, FragmentManager)} or * {@link #setup(Context, FragmentManager, int)}. */ @Override @Deprecated public void setup() { throw new IllegalStateException( "Must call setup() that takes a Context and FragmentManager"); } public void setup(Context context, FragmentManager manager) { super.setup(); mContext = context; mFragmentManager = manager; ensureContent(); } public void setup(Context context, FragmentManager manager, int containerId) { super.setup(); mContext = context; mFragmentManager = manager; mContainerId = containerId; ensureContent(); mRealTabContent.setId(containerId); // We must have an ID to be able to save/restore our state. If // the owner hasn't set one at this point, we will set it ourself. if (getId() == View.NO_ID) { setId(android.R.id.tabhost); } } private void ensureContent() { if (mRealTabContent == null) { mRealTabContent = (FrameLayout)findViewById(mContainerId); if (mRealTabContent == null) { throw new IllegalStateException( "No tab content FrameLayout found for id " + mContainerId); } } } @Override public void setOnTabChangedListener(OnTabChangeListener l) { mOnTabChangeListener = l; } public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { tabSpec.setContent(new DummyTabFactory(mContext)); String tag = tabSpec.getTag(); TabInfo info = new TabInfo(tag, clss, args); if (mAttached) { // If we are already attached to the window, then check to make // sure this tab's fragment is inactive if it exists. This shouldn't // normally happen. info.fragment = mFragmentManager.findFragmentByTag(tag); if (info.fragment != null && !info.fragment.isDetached()) { FragmentTransaction ft = mFragmentManager.beginTransaction(); ft.detach(info.fragment); ft.commit(); } } mTabs.add(info); addTab(tabSpec); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); String currentTab = getCurrentTabTag(); // Go through all tabs and make sure their fragments match // the correct state. FragmentTransaction ft = null; for (int i=0; i<mTabs.size(); i++) { TabInfo tab = mTabs.get(i); tab.fragment = mFragmentManager.findFragmentByTag(tab.tag); if (tab.fragment != null && !tab.fragment.isDetached()) { if (tab.tag.equals(currentTab)) { // The fragment for this tab is already there and // active, and it is what we really want to have // as the current tab. Nothing to do. mLastTab = tab; } else { // This fragment was restored in the active state, // but is not the current tab. Deactivate it. if (ft == null) { ft = mFragmentManager.beginTransaction(); } ft.detach(tab.fragment); } } } // We are now ready to go. Make sure we are switched to the // correct tab. mAttached = true; ft = doTabChanged(currentTab, ft); if (ft != null) { ft.commit(); mFragmentManager.executePendingTransactions(); } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mAttached = false; } @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); ss.curTab = getCurrentTabTag(); return ss; } @Override protected void onRestoreInstanceState(Parcelable state) { SavedState ss = (SavedState)state; super.onRestoreInstanceState(ss.getSuperState()); setCurrentTabByTag(ss.curTab); } @Override public void onTabChanged(String tabId) { if (mAttached) { FragmentTransaction ft = doTabChanged(tabId, null); if (ft != null) { ft.commit(); } } if (mOnTabChangeListener != null) { mOnTabChangeListener.onTabChanged(tabId); } } private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) { TabInfo newTab = null; for (int i=0; i<mTabs.size(); i++) { TabInfo tab = mTabs.get(i); if (tab.tag.equals(tabId)) { newTab = tab; } } if (newTab == null) { throw new IllegalStateException("No tab known for tag " + tabId); } if (mLastTab != newTab) { if (ft == null) { ft = mFragmentManager.beginTransaction(); } if (mLastTab != null) { if (mLastTab.fragment != null) { ft.detach(mLastTab.fragment); } } if (newTab != null) { if (newTab.fragment == null) { newTab.fragment = Fragment.instantiate(mContext, newTab.clss.getName(), newTab.args); ft.add(mContainerId, newTab.fragment, newTab.tag); } else { ft.attach(newTab.fragment); } } mLastTab = newTab; } return ft; } } 

Coloque este código después de haber configurado y agregó las pestañas a su FragmentTabHost, se eliminará y, a continuación, agregue las pestañas como el último niño en el TabHost. (Probado con android.support.v13.app.FragmentTabHost inflado desde xml y configurado con getChildFragmentManager () en un fragmento anidado)

 View tabs = (TabWidget) mTabHost.findViewById(android.R.id.tabs); ViewGroup parent = (ViewGroup) mTabHost.getChildAt(0); parent.removeView(tabs); parent.addView(tabs); 

Finalmente seguí este tutorial: Tabulaciones de Android con Fragmentos

Me rendí con FragmentTabHost, esto es más fácil (imho) para implementar, y pude poner el tabWidget en la parte inferior sin esfuerzo.

  • Acceder a TabHost desde otra actividad
  • Barra de pestañas ocultar problema android
  • Android - onTabChanged no se invoca al seleccionar una pestaña diferente
  • Nullpointer excepción en oncreateView () de fragmento
  • Modificar el indicador de pestañas dinámicamente en Android
  • Android: TabHost sin TabActivity
  • Actualización de iconos de pestaña de Android
  • Cómo inicializar el contenido de la pestaña cuando se inicializa la aplicación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.