Implementación de un TabListener utilizando la biblioteca de soporte
Estoy intentando implementar la navegación por pestañas, pero quiero asegurarme de que las personas que tengan versiones anteriores de Android todavía puedan usar mi aplicación.
La aplicación en mente ATM es bastante simple, sólo quiero ser capaz de entender cómo implementar el diseño y luego voy a añadir los bits que faltan.
- Android: ¿qué sustituyó android.support.v4.app.NavUtils en APIs posteriores?
- La imagen de Parallax no se muestra correctamente en la biblioteca de soporte 24.2.0
- ViewPager dentro de Fragmento pierde su contenido cuando se vuelve a mostrar el fragmento
- La Biblioteca de Soporte de Diseño de Android 24.2.1 hace que BottomSheet se abra al inicio
- NotifyDataSetChange no funciona en RecyclerView
De todos modos, tengo una actividad de contenedor que extiende la actividad de fragmentos (para asegurar la compatibilidad), y esta actividad crea un TabView con una ActionBar (creo que mi problema reside aquí). La aplicación intentará crear tres pestañas y agregarlas a ActionBar, y quiero asegurarme de que el usuario pueda desplazarse hacia delante y hacia atrás usando la navegación lateral.
Aquí está TabListener que estoy intentando implementar:
public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; public TabListener(Activity activity, String tag, Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } public void onTabSelected(Tab tab, FragmentTransaction ft) { if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else { ft.attach(mFragment); } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { ft.detach(mFragment); } } public void onTabReselected(Tab tab, FragmentTransaction ft) { } }
Aquí están mis importaciones, porque quería asegurarse de que estaba usando la biblioteca de soporte:
import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.view.Menu;
Sin embargo, Eclipse me está dando problemas con los métodos TabListener . Me dice lo siguiente: "El tipo LayoutContainer.TabListener debe implementar el método abstracto heredado ActionBar.TabListener.onTabSelected (ActionBar.Tab, FragmentTransaction)"
Cuando selecciono Añadir métodos no implementados Eclipse básicamente añade los métodos OnTabSelected OnTabReselected y OnTabUnselected , pero esta vez, pasando la versión no compatible del Fragmento ( android..app.Fragment ) como parámetro.
¿Alguna idea sobre cómo hacer otra implementación de la navegación lateral a través de la biblioteca de soporte para asegurar la compatibilidad?
- Android ContextCompat.checkSelfPermission () no encontrado
- No se puede resolver el símbolo al cambiar la versión de la biblioteca de soporte
- SDK de Facebook para Android duplicar la biblioteca de soporte en las dependencias
- Método llamada mActionBar = getActionBar () da error
- CoordinatorLayout ignora márgenes para vistas con ancla
- getSupportActionBar utilizando FragmentActivity
- ¿Cómo puedo acceder a getSupportFragmentManager () en un fragmento?
- ViewPager en un NestedScrollView
actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowHomeEnabled(false); actionBar.setDisplayShowTitleEnabled(false); tabA = actionBar.newTab().setText(""); tabB = actionBar.newTab().setText(""); Fragment fragmentA = new AFragmentTab(); Fragment fragmentB = new BFragmentTab(); tabA.setTabListener(new MyTabsListener(fragmentA)); tabB.setTabListener(new MyTabsListener(fragmentB)); actionBar.addTab(tabA); actionBar.addTab(tabB);
El listener de la pestaña es como sigue:
protected class MyTabsListener implements ActionBar.TabListener{ private Fragment fragment; public MyTabsListener(Fragment fragment){ this.fragment = fragment; } public void onTabSelected(Tab tab, FragmentTransaction ft){ ft.add(R.id.layout2, fragment, null); } public void onTabReselected(Tab tab, FragmentTransaction ft) { } public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(fragment); } }
Y luego hacer una clase para cada ficha:
public class BFragmentTab extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.login, container, false); } }
Pero tenga en cuenta que la barra de acción no es compatible con las versiones de Android inferiores a 3.0. Si desea utilizarlo en versiones anteriores le sugiero que use la biblioteca de actionBarSherlock.
Hmmm Mientras que las obras de Malek no responden directamente a la pregunta ..
Simplemente puede ignorar la transacción de fragmentos que recibe en la devolución de llamada y utilizar su propia:
android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction();
Sólo asegúrese de que su actividad es una FragmentActivity y podrá iniciar una nueva transacción de fragmentos.
También el método replace () en el fragmentTransaction es mucho más conveniente que add () y remove ()
La clave es usar
import android.support.v7.app.ActionBar;
… más bien que …
import android.app.ActionBar;
Eso evita la ingeniosa solución Nelson Ramírez.
El siguiente ejemplo completo, basado en la documentación oficial , se probó para funcionar desde Android 3.0, API 11
package com.example.myapp; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.view.*; import android.widget.TextView; public class NavigationTabsBasicDemoActivity extends ActionBarActivity { static public class TabListener<T extends Fragment> implements ActionBar .TabListener { private Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; /** * Constructor used each time a new tab is created. * * @param activity The host Activity, used to instantiate the * fragment * @param tag The identifier tag for the fragment * @param pClass The fragment's Class, used to instantiate the * fragment * @see <a * href="http://developer.android.com/guide/topics/ui/actionbar * .html#Tabs"> * Developers Guide > Action Bar > Adding Navigation Tabs</a> */ public TabListener(Activity activity, String tag, Class<T> pClass) { mActivity = activity; mTag = tag; mClass = pClass; } @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else { // If it exists, attach it in order to show it ft.attach(mFragment); } } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { if (mFragment != null) { // Detach the fragment, because another one is about to be // attached. ft.detach(mFragment); } } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { // Do nothing. } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // No need for setContentView() to be used, Instead we use the root // android.R.id.content as the container for each fragment, // which is set in the TabListener ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(true); ActionBar.Tab tab = actionBar.newTab().setText("Artist").setTabListener( new TabListener<PlaceholderFragment>(this, "artist", PlaceholderFragment .class)); actionBar.addTab(tab); tab = actionBar.newTab().setText("Album").setTabListener( new TabListener<PlaceholderFragment>( this, "album", PlaceholderFragment.class)); actionBar.addTab(tab); } /** * In this example use one Fragment but display different data based on * which * tab is shown. In production you'd probably use a separate fragment. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate( R.layout.fragment_navigation_tabs_basic_demo, container, false); TextView outputTextView = (TextView) rootView.findViewById( R.id.output_textView); outputTextView.setText("Hello " + getTag()); return rootView; } } }
Quería implementar @ nelson-ramirez pero tenía un error al acceder a mActivity, así que esta es una combinación de esas dos respuestas, y funciona para mi proyecto, que utiliza una pestaña de navegación con inicio de sesión en Facebook (que requiere la biblioteca support.v4). Las claves son, la creación de una mActivity privado que luego pasar y asignar al iniciar el oyente, y la creación de su propia Fragmento de transacción, no utilizando el del argumento. Además, cambie la actividad principal a FragmentActivity, utilizando la biblioteca v4, que permite el acceso a getSupportFragmentManager ().
public class MyTabListener implements ActionBar.TabListener{ private Fragment fragment; private FragmentActivity mActivity; public MyTabListener(Fragment fragment, FragmentActivity activity){ this.fragment = fragment; this.mActivity = activity; } @Override public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) { android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.replace(R.id.fragment_container, fragment); fft.commit(); } @Override public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) { android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction(); fft.remove(fragment); } @Override public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) { } }
¿Alguna idea sobre cómo hacer otra implementación de la navegación lateral a través de la biblioteca de soporte para asegurar la compatibilidad?
Solución alternativa
A partir del 29 de mayo de 2015, puede utilizar la Biblioteca de soporte de diseño de Android . Incluye un Tab Layout y soporta dispositivos Android 2.1 o superiores.
- Cómo evitar que se compruebe un CheckBox?
- Encontrar el color dominante de una imagen en un @drawable de Android