2012-10-10 19 views
6

Estoy usando un adaptador de fragmento de buscapersonas para crear una instancia de mi clase de fragmento. Puedo hacerlo pero mi problema es que mi método getItem() recibe dos llamadas. está creando un problema adicional. ¿Puede explicarme por qué está sucediendo?El método getItem() recibe dos llamadas cuando se utiliza el Adaptador de buscapersonas

package com.creatiosoft.rssfeed.adaptor; 

    import android.content.Context; 
    import android.support.v4.app.Fragment; 
    import android.support.v4.app.FragmentManager; 
    import android.support.v4.app.FragmentPagerAdapter; 
    import android.util.Log; 

    import com.creatiosoft.rssfeed.utils.RssItem; 
    import com.viewpagerindicator.IconPagerAdapter; 

    public class NewsFeedsAdapter extends FragmentPagerAdapter implements 
      IconPagerAdapter { 

     int[] icon = null; 
     String[] content = null; 
     String[] URLs = null; 
     Context cont; 

     public NewsFeedsAdapter(FragmentManager fm, Context context) { 
      super(fm); 
      Log.i("jk", "constructor"); 
      this.cont = context; 
      RssItem newsFeedAppliaction = (RssItem) cont; 
      /* 
      * Retrieving the values of the Icons and contents from the application 
      * class in utils package 
      */ 
      icon = newsFeedAppliaction.getICONS(); 
      content = newsFeedAppliaction.getCONTENT(); 
      URLs = newsFeedAppliaction.getURL(); 

     } 

     /** instantiate a new fragment class */ 
     @Override 
     public Fragment getItem(int position) { 
      Log.i("yt", "hello" + position); 
      return TestFragment.newInstance(position % content.length, cont); 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      return content[position % content.length].toUpperCase(); 
     } 

     public int getIconResId(int index) { 
      return icon[index]; 
     } 

     /** return the no of views on the basis of array items */ 
     @Override 
     public int getCount() { 

      Log.i("hi", "length" + content.length); 
      return content.length; 
     } 
    }  

Estoy llamando adaptador con este código:

NewsFeedsAdapter adapter = new NewsFeedsAdapter(
       getSupportFragmentManager(), getApplicationContext()); 
     /** 
     * get the id of the view pager declared in the xml resource and set the 
     * adaptor on the view pager 
     */ 
     ViewPager pager = (ViewPager) findViewById(R.id.pager); 
     pager.setAdapter(adapter); 
     //pager.setCurrentItem(0); 

     /** 
     * Tab page indicator class is used to indicate the tabs and is accessed 
     * from the library class 
     */ 
     TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator); 
     indicator.setViewPager(pager); 

Respuesta

2

En el método de getItem se crea una nueva instancia de un fragmento. Este es terrible. Te pone en la situación en la que te encuentras ahora. Lo que estás haciendo es crear un nuevo objeto anónimo que vivirá días como lo has especificado. Pero cuando el malvado sistema Android decide que necesita volver a hablar con tu Fragmento y lo solicita desde tu adaptador, le estás diciendo "¡No, no quiero!" y en cambio darle un nuevo fragmento EXACTAMENTE lo mismo que su anterior padre.

Para corregir esto, infle todo su fragmento antes de tiempo y luego devuelve el fragmento correcto. O si prefieres, no lo hagas. Pero mantenga un registro de las instancias que ha creado para que pueda devolver los fragmentos ya creados.

No sé exactamente por qué se llama dos veces: no he rastreado la fuente de v4, pero probablemente se haya hecho para asegurar que el elemento se recupera realmente o el sistema entró en un estado donde el elemento anterior tenía que estar revisado.

En conclusión, retenga instancias creadas - especialmente para objetos tan pesados ​​como fragmentos, vistas y actividades.

class Adapter extends MyWhateverAdapter { 
    Fragment[] myLovelyFragments; 

    public Adapter() { 
     // Instantiate your fragments and place them into myLovelyFragments 
    } 

    public int getFragmentCount() { 
     return myLovelyFragments.length; 
    } 

    public Fragment getItem(int position) { 
     return myLovelyFragments[position]; 
    } 
} 
+0

amablemente denme el código de muestra si es posible. – yokees

+0

@ Rishabh.CreatioSoft Aquí tienes. :) – AedonEtLIRA

+0

pero dime una posición de cosa me devuelve 0 y 1 tanto en getItem cuando PagerAdapterCall.So estamos obteniendo objeto de fragmento en 1 posición.Así que cómo puede decirnos su código correcto. – yokees

11

Tenga en cuenta que el localizador mantiene al menos una página por delante. Lo que significa que cuando se crea el buscapersonas, crea al menos dos páginas, la que muestra y la siguiente, para permitir "paginación".

0

El problema que probablemente tenga no son las llamadas múltiples del método getItem(). Después de un poco de investigación, me encontré con que el método isViewFromObject() tiene un papel muy importante y en su documentación se dice que "This method is required for a PagerAdapter to function properly."

también encontré que la forma correcta para implementar el método es el siguiente:

@Override 
public boolean isViewFromObject(View view, Object object) { 
    if(object != null){ 
     return ((Fragment)object).getView() == view; 
    }else{ 
     return false; 
    } 
} 

Usted puede mirar here.

Cuestiones relacionadas