2013-03-05 17 views
19

nella mia richiesta, ho usato il ViewPager. Come,Android: FragmentPagerAdapter: metodo getItem chiamato due volte al primo tempo

(say main.xml) 

<android.support.v4.view.ViewPager 
    android:id="@+id/viewPager" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_above="@+id/register_header" /> 

e creare oggetto ViewPager e ViewPagerAdapter (che si estende FragmentPagerAdapter) oggetto in FragmentActivity.

_mViewPager = (ViewPager) findViewById(R.id.viewPager); 

_adapter = new ViewPagerAdapter(getApplicationContext(), 
     getSupportFragmentManager()); 

_mViewPager.setAdapter(_adapter); 

E la classe adattatore è come,

public class ViewPagerAdapter extends FragmentPagerAdapter { 
    private Context _context; 
    private FragmentManager manager; 
    private Fragment f; 
    private String classname="ViewPagerAdapter"; 
    public ViewPagerAdapter(Context context, FragmentManager fm) { 
     super(fm); 
     _context=context; 
     manager=fm; 
     } 
    @Override 
    public Fragment getItem(int position) { 
     Log.i(classname,"getItem called"+position); 
     f = new Fragment(); 
     f=MyFragment.newInstance(); 
     Bundle args = new Bundle(); 
     args.putInt("position", position); 
     f.setArguments(args); 
     return f; 
    } 

    @Override 
    public int getCount() { 
     return User.getPageCount(); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     return POSITION_NONE; 
    } 
} 

E in MyFragment classe,

In onResume, devo memorizzare i wigets oggetto alla variabile statica comune.

public void onResume() { 
     super.onResume(); 
     pageIndex = getArguments().getInt("position");  
     User.useTextview1=textview1; 
     User.useTextview2= textview2; 
     User.current_pageIndex=pageIndex; 



    } 

Devo aggiornare le visualizzazioni di testo ottenute dalla classe Utente in FragmentActivity. Il mio problema è il metodo getItem() viene chiamato due volte la prima volta In Fact, la vista visualizzata nell'emulatore è 0 ° indice, ma ha ottenuto il 1 ° valore dell'indice in FragmentActivity. Se ho smesso la chiamata di metodo di getItem() sulla seconda volta, posso in grado di ottenere l'indice di riferimento TextView 0a nel FragmentActivity.

Si prega di fornire me il modo migliore per farlo.

Grazie

+0

hai superare questo problema? – GvSharma

+0

@GVSharma no, non ho – Sridhar

+0

ho capito .... scriverò qui cosa ho fatto .... – GvSharma

risposta

17

Il FragmentPagerAdapter crea un'istanza 2 Fragments su start, per l'indice 0 e per l'indice 1. Se si desidera ottenere i dati dal Fragment che è sullo schermo, è possibile utilizzare per la setOnPageChangeListenerPager per ottenere corrente posizione. Poi hanno SparseArray con WeakReference ai tuoi frammenti. Aggiorna la matrice nella chiamata getItem. Quando viene chiamato onPageSelected uso quella posizione per ottenere riferimento al diritto Fragment e aggiornare i dati User.

inizializzazione di array:

private SparseArray<WeakReference<MyFragment>> mFragments = new SparseArray<WeakReference<MyFragment>>(3); 
+0

che cos'è Sparray? – Sridhar

+0

È un array che mappa gli oggetti per determinate posizioni. In getItem lo si utilizza in questo modo: myMemberSparseArrayObject.put (posizione, nuovo WeakReference (f)); – Niko

+0

ok, quindi FragmentActivity manterrà il diritto myMemberSparseArrayObject? – Sridhar

1

Il mio problema è il metodo getItem() viene chiamato due volte sul primo tempo

Questo non è il problema, questo è default feature of FragmentPagerAdapter. È utile passare da questa pagina alla successiva e alla precedente.

la vista visualizzata nell'emulatore è indice di 0a, ma ha ottenuto 1 ° valore Indice nel FragmentActivity

Ho avuto lo stesso problema, e so perché. Questo perché tu used same Fragment in View Pager.

Come risolvere questo problema è separate Fragments by using different Fragment.

+0

ho implementato questo ... dentro ho bisogno di cliccare su ogni pagina e che andrà ad altro frammento ... ma sta dando di default posizioni sbagliate ... capisco che rispondi in una certa misura ... puoi spiegare con maggiore chiarezza – GvSharma

+0

Sembra che tu abbia un altro problema 'sta dando di default posizioni sbagliate '. Puoi usare 'viewpager.getCurrentItem (position)' per indicare a quale pagina deve andare dopo aver cliccato su alcuni pulsanti. –

+0

ho la soluzione .... grazie per la tua risposta rapida – GvSharma

1

nel metodo getItem ho scritto questo ..

@Override 
public Fragment getItem(int index) { 
    EditFragment frag = new EditFragment(); 
    Bundle args = new Bundle(); 
    args.putSerializable("currentItem", itemsList.get(index)); 
    frag.setArguments(args); 
    return (frag); 
} 

qui itemsList.get (index) è l'oggetto della classe del modello che userò nella classe EditFragment. ecco quello.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 
    View result = inflater.inflate(R.layout.pager_fragment_layout, container, false); 
    image = (ImageView)result.findViewById(R.id.pager_image); 
    text = (TextView)result.findViewById(R.id.pager_item_desc); 
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity()).build(); 
    ImageLoader.getInstance().init(config); 
    imLoader = ImageLoader.getInstance(); 

      ****NOTE 
    final SwapItems itemList = (SwapItems) getArguments().getSerializable("currentItem"); 

    imagePath = itemList.getPaths().get(0); 
    imLoader.displayImage(imagePath,image); 
    text.setText(itemList.getItemDescription()); 

    image.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Fragment fragment = new ItemImagesFragment(); 
      FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
      FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
      Bundle bundle = new Bundle(); 
      bundle.putSerializable("val", itemList); 
      fragment.setArguments(bundle); 
      fragmentTransaction.replace(R.id.content_frame, fragment); 
      fragmentTransaction.addToBackStack(null); 
      fragmentTransaction.commit(); 
     } 
    }); 
    return result; 
} 

NOTA: qui sto ricevendo oggetto modello swapitems dal precedente metodo getItem è 'finale'. questo risolve il mio problema In precedenza ero inizializzato lo stesso oggetto con statico come modificatore.

vostra speranza sarà anche chiaro

0

è possibile utilizzare questo metodo per aggiornare le vostre opinioni

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 

    if (isVisibleToUser) { 
     // Fetch data or something... 
    } 
} 
0

Ho affrontato lo stesso problema - il metodo getItem() è stato chiamato due volte. Non so se i tuoi scopi di usare quel metodo da parte mia sono di innescare cambiamenti in un'attività di hosting quando appare una nuova diapositiva.

Bene, in primo luogo getItem() non è un metodo corretto per ottenere l'evento di visualizzazione di una nuova diapositiva.

Ho utilizzato il listener ViewPager.OnPageChangeListener su ViewPager stesso per questo scopo. Ecco quello che ho fatto:

In attività che contiene frammenti di diapositive:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.signature_wizard_activity); 

    // Instantiate a ViewPager and a PagerAdapter. 
    mPager = (ViewPager) findViewById(R.id.pager); 
    mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); 
    mPager.setAdapter(mPagerAdapter); 
    mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      onSlideChanged(position); // change color of the dots 
     } 
     @Override 
     public void onPageSelected(int position) {} 
     @Override 
     public void onPageScrollStateChanged(int state) {} 
    }); 
} 

onPageScrolled() viene chiamato ogni volta che compare la diapositiva, come parametro si ottiene la posizione attuale della diapositiva che è mostrato. La cosa bella è che viene chiamata anche la prima volta che appare, non solo quando è stata cambiata la diapositiva.

Quando può essere utilizzato? Ad esempio se si dispone di alcune attività della procedura guidata con ViewPager in cui si fanno scorrere i frammenti con alcuni suggerimenti, è probabile che si desideri avere una barra con punti grigi sotto il cursore che rappresenterebbe il numero di diapositive in totale e uno dei punti sarà essere di colore diverso che rappresenta la diapositiva corrente. In questo caso, ViewPager.OnPageChangeListener e il metodo onPageScrolled() saranno l'opzione migliore.

Oppure con pulsanti PREV. e NEXT che cambiano le diapositive e si desidera disabilitare PREV. pulsante sulla prima diapositiva e disabilita il pulsante NEXT sull'ultima diapositiva. Ecco come si fa all'interno onPageScrolled metodo():

@Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
      if(position == 0){ 
       prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500)); 
       prevBtn.setEnabled(false); 
      }else{ 
       prevBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue)); 
       prevBtn.setEnabled(true); 
      } 

      if(position == NUM_PAGES -1){ 
       nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_grey_500)); 
       nextBtn.setEnabled(false); 
      }else{ 
       nextBtn.setTextColor(ContextCompat.getColor(SignatureWizardActivity.this, R.color.main_blue)); 
       nextBtn.setEnabled(true); 
      } 
     } 

dove NUM_PAGES è una costante con il numero totale di diapositive

Problemi correlati