Tengo problema siguiente:
Tengo una actividad en la que tengo dos pestañas que se hacen tanto como fragmentos usando FragmentPagerAdapter
En algún momento me gustaría cambiar de Vista de uno de estos fragmentos, pero no soy capaz de findFragmentById() o findFragmentByTag() soy incapaz de establecer el id, porque yo no estoy declarando Fragmento de XML, debido a la FragmentPagerAdapter
Y cuando estoy tratando de establecer la etiqueta que estoy recibiendo siguiente problema:

08-15 21:46:23.805: E/AndroidRuntime(9297): java.lang.IllegalStateException: Can't  change tag of fragment Companies{416d7b78 id=0x7f04002e companies}: was companies now android:switcher:2130968622:1

Mi código de la buscapersonas FragmentPagerAdapter:

public class TabsAdapter extends FragmentPagerAdapter implements    ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final FragmentActivity mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
FragmentTransaction ft=mContext.getSupportFragmentManager().beginTransaction();
Fragment fragment=Fragment.instantiate(mContext, info.clss.getName(), info.args);
if(position==1){
ft.add(mViewPager.getId(), fragment, "companies");
}else{
ft.add(mViewPager.getId(), fragment);
}
Log.v("FRAGMENT ID", "fragment tag: "+fragment.getTag());
ft.commit();
Log.v("FRAGMENT ID", "fragment tag: "+fragment.getTag());
return fragment;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
new Thread(new Runnable() {
@Override
public void run() {
MainActivity.this.hideKeyboard();
}
}).start();
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);                   
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}

Gracias de antemano por sus respuestas.

InformationsquelleAutor ziky90 | 2012-08-15

5 Comentarios

  1. 52

    Los Fragmentos suministrados por el FragmentPagerAdapter son auto-etiquetado cuando se está instanciado. Usted puede recuperar la etiqueta con este método:

    private static String makeFragmentName(int viewPagerId, int index) {
    return "android:switcher:" + viewPagerId + ":" + index;
    }

    Referencia: reutilización de fragmentos en un fragmentpageradapter

    • Gracias, esto funcionó para mí.
    • Nota para la gente como yo: viewId es el identificador de la ViewPager
    • dios los bendiga!!
    • Pensé que el método es poner en la clase se extiende FragmentPagerAdapter, pero el método debe ser acaba de poner en el Fragment clase.
    • Los fragmentos no siempre son utilizados en viewpagers pero FragmentPagerAdapter se utiliza siempre con Viewpagers. No tendría sentido tener un Fragment.
    • Lo siento por mi culpa no es del fragmento, es la Actividad. En mi caso hay una Activity con ViewPager en el interior. Y el ViewPager contiene un FragmentPagerAdapter de 2 fragmentos. Así que para la reutilización de fragmentos puedo poner el método en el Activity a findFragmentByTag() en el ViewPager diseño.
    • ¿Por qué hacer esto? Quiero decir, si estás generando el fragmento nombre de la posición, acaba de obtener directamente por la posición. .getSupportFragmentManager().getFragments().get(posición).getChildFragmentManager().getFragments().get(posición)
    • Este es el camino correcto : stackoverflow.com/questions/6976027/…

  2. 22

    Con esta función usted puede encontrar el fragmento de pager posición del adaptador.

    public Fragment findFragmentByPosition(int position) {
    FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
    return getSupportFragmentManager().findFragmentByTag(
    "android:switcher:" + getViewPager().getId() + ":"
    + fragmentPagerAdapter.getItemId(position));
    }

    Código de ejemplo para la v4 apoyo de la api.

  3. 6

    He encontrado un poco menos bruto manera de conseguir una manija en un Fragment creado por un FragmentPagerAdapter.
    En lugar de imitar la forma en que las etiquetas se crean, anular instantiateItem(), obtener la Fragment devuelto por la superclase, y guardar la etiqueta en TabInfo. Esto funciona para mí en la API >= 15, puede trabajar con menores. Esto todavía hace algunas suposiciones acerca de código privado.

    static final class TabInfo {
    private final Class<?> clss;
    private final Bundle args;
    private String tag; //** add this
    TabInfo(Class<?> _class, Bundle _args) {
    clss = _class;
    args = _args;
    }
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    final Fragment fragment = (Fragment) super.instantiateItem(container, position);
    final TabInfo info = mTabs.get(position);
    info.tag = fragment.getTag(); //set it here
    return fragment;
    }

    O en la API < 16, creo que instantiateItem() toma un View() en lugar de ViewGroup(), como este:

    public Object instantiateItem(View container, int position);

    A continuación, permitir que una manera de conseguir el Fragment, manteniendo el hack de contenidos.

    public Fragment getFragment(int index) {
    return mContext.getFragmentManager().findFragmentByTag(mTabs.get(index).tag);
    }

    Para que funcione, la declaración de mContext necesita cambiar para Activity, se pasa en un Activity de todos modos:

    private final Activity mContext;
    • tratando de aplicar esta solución, pero super.instantiateItem(contenedor, posición) lanza NPE para mí ambos FragmentPagerAdapter y FragmentStatePagerAdapter
  4. 1

    Un enfoque más simple para esto es conseguir que las Etiquetas directamente desde el Fragmento de Administrador; como esta:

    fm.getFragments().get(0).getTag()

    Puede reemplazar la posición, dependiendo del fragmento necesita la etiqueta. Espero que esto ayude a los demás!.

Dejar respuesta

Please enter your comment!
Please enter your name here