2012-08-15 10 views
33

he siguiente problema: 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 Vista de uno de estos fragmentos, pero no soy capaz de findFragmentById() o findFragmentByTag() soy incapaz de establecer la identificación, porque no estoy declarando fragmento en XML, debido a la FragmentPagerAdapter Y cuando estoy tratando de establecer la etiqueta Obtengo el siguiente problema:Android conseguir fragmento que está en FragmentPagerAdapter

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 del localizador 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.

Respuesta

50

Los fragmentos suministrados por FragmentPagerAdapter se etiquetan automáticamente cuando se crean instancias. Puede recuperar la etiqueta con este método:

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

Reference: reusing fragments in a fragmentpageradapter

+0

Gracias, esto funcionó para mí. – ziky90

+15

Nota para personas como yo: viewId es el id del ViewPager – htafoya

+0

¡Dios te bendiga! – user1767754

6

he encontrado una manera un poco menos bruta para conseguir una manija en un Fragment creado por un FragmentPagerAdapter. En lugar de imitar la forma en que se crean las etiquetas, anule instantiateItem(), obtenga Fragment devuelto por la superclase y guarde la etiqueta en TabInfo. Esto funciona para mí en API> = 15, puede funcionar con menor. Esto todavía hace algunas suposiciones sobre el 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 instantiateItem() toma un View() en lugar de ViewGroup(), así:

public Object instantiateItem(View container, int position); 

luego permitir que una manera de conseguir la Fragment, manteniendo el hack contenía.

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

Para que funcione, la declaración de mContext tiene que cambiar a Activity, se pasa como un Activity todos modos:

private final Activity mContext; 
+1

tratando de aplicar esta solución, pero ** super.instantiateItem (contenedor, posición) ** arroja ** NPE ** para mí tanto FragmentPagerAdapter como FragmentStatePagerAdapter – Sash0k

21

Con esta función se puede encontrar el fragmento por la posición del adaptador buscapersonas.

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

Código de ejemplo para api apoyo v4.

+0

http://stackoverflow.com/ preguntas/6976027/reusing-fragments-in-a-fragmentpageradapter/29287415 # 29287415 –

-1

Es muy tarde para responder a esta pregunta, pero he buscado mucho, nadie me dice la respuesta exacta, podría ser que alguien lo encontrara útil.

he puesto mis fragmentos a través FragmentPagerAdapter y lo hice comunicación entre fragmentos

https://developer.android.com/training/basics/fragments/communicating.html#Deliver

siguiendo este enlace y para FindFragmentById i simplemente utilizado viewpager.getId() en el mainactivity.

1

Un enfoque más simple para esto es obtener las etiquetas directamente desde el administrador de fragmentos; como este:

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

Puede reemplazar la posición, dependiendo del fragmento para el que necesita la etiqueta. Espero que esto ayude a otros !.

Cuestiones relacionadas