support last android android-fragments android-support-library

android - last - Implementando un TabListener usando la biblioteca de soporte



com.android.support:design 26 (5)

Estoy tratando de implementar la navegación con pestañas, pero quiero asegurarme de que las personas que tienen versiones anteriores de Android todavía puedan usar mi aplicación.

La aplicación en mente ATM es bastante simple, solo quiero poder entender cómo implementar el diseño y luego agregaré los bits faltantes.

De todos modos, tengo una actividad de contenedor que extiende la actividad de fragmentos (para garantizar la compatibilidad), y esta actividad crea un TabView utilizando una barra de acción (creo que mi problema reside aquí). La aplicación intentará crear tres pestañas y agregarlas a la barra de acción, y quiero asegurarme de que el usuario pueda desplazarse hacia adelante y hacia atrás con la navegación lateral.

Aquí está TabListener que estoy tratando de 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 asegurarme 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 de TabListener . Me dice lo siguiente: "El tipo LayoutContainer.TabListener debe implementar el método abstracto heredado ActionBar.TabListener.onTabSelected (ActionBar.Tab, FragmentTransaction)"

Cuando selecciono Agregar métodos no implementados, Eclipse básicamente agrega los métodos OnTabSelected OnTabReselected y OnTabUnselected , pero esta vez, pasa la versión no compatible del fragmento ( android..app.Fragment ) como parámetro.

¿Alguna idea sobre cómo hacer otra implementación de navegación lateral a través de la biblioteca de soporte para asegurar la compatibilidad?


¿Alguna idea sobre cómo hacer otra implementación de 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 diseño de pestaña y es compatible con dispositivos Android 2.1 o superiores.


La clave es usar

import android.support.v7.app.ActionBar;

... más bien que ...

import android.app.ActionBar;

Eso evita la inteligente solución que Nelson Ramírez publicó.

El siguiente ejemplo completo, basado en la documentación oficial , fue probado 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 tuve un error al acceder a mActivity, por lo que esta es una combinación de esas dos respuestas, y funciona para mi proyecto, que usa una navegación con pestañas con inicio de sesión de Facebook (que requiere la biblioteca support.v4). las claves son crear un mActivity privado que luego pasas y asignas al iniciar el oyente, y crear tu propia Transacción de Fragmentos, sin usar la 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) { } }


hmmm mientras que el trabajo de Malek no responde directamente a la pregunta ..

Simplemente puede ignorar la transacción de fragmento que obtiene en la devolución de llamada y usar la suya propia:

android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction();

Solo asegúrese de que su actividad sea FragmentActivity y podrá comenzar una nueva transacción de fragmentos.

Además, el método replace () en fragmentTransaction es mucho más conveniente que add () y remove ()


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 oyente de la pestaña es el siguiente:

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 haces una clase para cada pestaña:

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 versiones de Android inferiores a 3.0. Si quieres usarlo en versiones anteriores, te sugiero que uses la biblioteca actionBarSherlock.