2013-02-15 16 views
7

Sto lavorando a un'applicazione che ha una vista ViewPager, Ho creato un PagerAdapter, che ha la vista, il metodo instantiateItem() di PagerAdapter viene chiamato due volte in create() Non so perché, qualcuno può aiutarmi con questo?Classe PagerAdapter chiamata più volte

Ecco il mio codice,

  View PagerView; 
     MyPagerAdapter adapter; 
     ViewPager pager; 

      adapter = new MyPagerAdapter();  
    pager.setAdapter(adapter); 
    pager.setCurrentItem(0); 

public class MyPagerAdapter extends PagerAdapter { 

     @Override 
     public Object instantiateItem(final View collection, final int position) { 
      Log.d("Inside", "Pager"); 
      PagerView = new View(collection.getContext()); 
      LayoutInflater inflater = (LayoutInflater) collection.getContext() 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      PagerView = inflater.inflate(R.layout.tablemenu, null, false); 
      tbMenuDetails = (TableLayout) PagerView 
        .findViewById(R.id.Menutable1); 
      scrollview = (ScrollView) PagerView.findViewById(R.id.scrollView1); 
      tbMenuDetails.removeAllViews(); 
      removeTableRows(); 
      createTableLayout(position); 
      String str[][] = datasource.GetSubMenuDetailsFromMenuId(MenuIdlst 
        .get(position).trim()); 
      Log.d("Str", "" + str.length); 
      for (int i = 0; i < str.length; i++) { 
       addRows(str[i][1], str[i][2], str[i][0], str[i][3], position); 
       Log.d("Message", "Pos " + position + " SubMenuName" + str[i][2] 
         + " SubMenuId" + " " + str[i][0] + " TypeID" + " " 
         + str[i][3]); 
      } 

      // View view = inflater.inflate(resId, null); 
      ((ViewPager) collection).addView(PagerView, 0); 

      return PagerView; 
     } 

     @Override 
     public void destroyItem(final View arg0, final int arg1, 
       final Object arg2) { 
      ((ViewPager) arg0).removeView((View) arg2); 

     } 

     @Override 
     public boolean isViewFromObject(final View arg0, final Object arg1) { 
      return arg0 == ((View) arg1); 

     } 

     @Override 
     public void finishUpdate(View arg0) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void restoreState(Parcelable arg0, ClassLoader arg1) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public Parcelable saveState() { 
      // TODO Auto-generated method stub 
      return null; 
     } 

     @Override 
     public void startUpdate(View arg0) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public int getCount() { 
      // TODO Auto-generated method stub 
      return MenuIdlst.size(); 
     } 

    } 

Aiutateci

+0

Nessuno mi può aiutare ?? – hemant

+0

come stai istanziando il cercapersone con i frammenti? incolla quel codice(codice onCreate()) – SKK

+0

adapter = new MyPagerAdapter(); \t \t \t \t pager.setAdapter (adattatore); \t \t pager.setCurrentItem (0); \t \t pager.setOffscreenPageLimit (0); – hemant

risposta

5

Se si decide di utilizzare Frammenti, non implementare PagerAdapter. Invece, estendere FragmentPagerAdapter o FragmentStatePagerAdapter:

private class MyPagerAdapter extends FragmentStatePagerAdapter { 
    public MyPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public int getCount() { 
     return NUMBER_OF_PAGES_IN_PAGER; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // Implement the static method newInstance in MyFragment.java yourself. 
     // It should return you a brand new instance of MyFragment, basically using 
     // the code you had in your original instantiateItem method. 
     return MyFragment.newInstance(position, ... etc ...); 
    } 
} 

Poi, nel tuo attività:

myPagerAdapter = new MyPagerAdapter(getFragmentManager()); 
// or myPagerAdapter = new MyPagerAdapter(getSupportFragmentManager()); 
myViewPager.setAdapter(myPagerAdapter); 

per maggiori informazioni su come utilizzare Frammenti e ViewPagers: https://developer.android.com/reference/android/app/Fragment.html https://developer.android.com/reference/android/support/v4/view/ViewPager.html https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

+0

-Streets Of Boston Dove dovrei inizializzare le viste che si trovano all'interno di ViewPager? – hemant

+0

-Streets Of Boston getItem (int pos) dovrebbe restituire cosa, per favore guidami nei dettagli Signore. – hemant

+0

Il getItem (int pos) restituisce il frammento che si desidera mostrare nella pagina "pos". Il frammento (MyFragment) è una sottoclasse di Fragment. Si creano le Viste in questa implementazione di sottoclasse di onCreateView: https://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os. Bundle) –

3

ViewPager dal precarico di default una pagina avanti/prima della pagina corrente (se presente). Non hai detto se è stato chiamato per la stessa posizione o posizione diversa.

+0

Quindi cosa dovrei fare? – hemant

+0

Se non vuoi che il pre-caricamento avvenga, puoi chiamare 'setOffscreenPageLimit (0)' sul tuo 'ViewPager'. http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int) –

+0

È ancora chiamato per due volte – hemant

2

Utilizzare i frammenti per ciascuna vista in un cercapersone.

scrivere il codice seguente nel metodo onCreate() dello FragmentActivity.

List<Fragment> fragments = new Vector<Fragment>(); 

//for each fragment you want to add to the pager 
Bundle page = new Bundle(); 
page.putString("url", url); 
fragments.add(Fragment.instantiate(this,MyFragment.class.getName(),page)); 

//after adding all the fragments write the below lines 

this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments); 

mPager.setAdapter(this.mPagerAdapter); 

Una definizione frammento campione:

public class MyFragment extends Fragment { 


public static MyFragment newInstance(String imageUrl) { 

final MyFragment mf = new MyFragment(); 

    final Bundle args = new Bundle(); 
    args.putString("somedata", "somedata"); 
    mf.setArguments(args); 

    return mf; 
} 

public MyFragment() {} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    String data = getArguments().getString("somedata"); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    // Inflate and locate the main ImageView 
    final View v = inflater.inflate(R.layout.my_fragment_view, container, false); 
    //... 
    return v; 
} 

seguo questo metodo ogni volta devo usare ViewPager. Spero che questo ti aiuti. Non riuscivo a capire perché il tuo metodo di instantiate veniva chiamato due volte dalle informazioni che hai fornito.

+0

ok proverò a utilizzare questo primo – hemant

+0

ha funzionato per te? – SKK

+0

NO non sto ottenendo come implementare questa è la mia app, puoi suggerirmi le modifiche nel mio codice – hemant

3

ViewPager.setOffscreenpageLimit(int) ha un valore minimo di 1. È possibile visualizzarlo dallo source code for ViewPager:

private static final int DEFAULT_OFFSCREEN_PAGES = 1; 

... 

/** 
    * Set the number of pages that should be retained to either side of the 
    * current page in the view hierarchy in an idle state. Pages beyond this 
    * limit will be recreated from the adapter when needed. 
    * 
    * <p>This is offered as an optimization. If you know in advance the number 
    * of pages you will need to support or have lazy-loading mechanisms in place 
    * on your pages, tweaking this setting can have benefits in perceived smoothness 
    * of paging animations and interaction. If you have a small number of pages (3-4) 
    * that you can keep active all at once, less time will be spent in layout for 
    * newly created view subtrees as the user pages back and forth.</p> 
    * 
    * <p>You should keep this limit low, especially if your pages have complex layouts. 
    * This setting defaults to 1.</p> 
    * 
    * @param limit How many pages will be kept offscreen in an idle state. 
    */ 
    public void setOffscreenPageLimit(int limit) { 
     if (limit < DEFAULT_OFFSCREEN_PAGES) { 
      Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + 
        DEFAULT_OFFSCREEN_PAGES); 
      limit = DEFAULT_OFFSCREEN_PAGES; 
     } 
     if (limit != mOffscreenPageLimit) { 
      mOffscreenPageLimit = limit; 
      populate(); 
     } 
    } 

Si dovrebbe vedere un messaggio di avviso in Logcat se si tenta di impostare a zero.

Il limite inferiore è 1 per un ottimo motivo. La pagina adiacente deve essere già caricata quando si scorre il cercapersone - altrimenti non si vedrà nulla per la pagina successiva. Se riesci a forzare il limite della pagina fuori schermata a zero, probabilmente vedrai semplicemente una pagina nera e vuota mentre scorri dalla prima alla seconda pagina. Se hai un problema particolare con la prima e la seconda pagina create all'inizio, prova a mirare e correggerlo.

+0

ha senso ... buona cattura. –

-1

Le modifiche apportate sono essenziali per il metodo isViewFromObject(). E 'molto importante e in essa di documentazione si dice che "This method is required for a PagerAdapter to function properly."

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

si può guardare here.

Problemi correlati