2013-05-02 16 views
14

Sto usando un viewpager per visualizzare del testo su più pagine. Sto cercando di ottenere la vista corrente e seleziono una nuova pagina. Il motivo che voglio per ottenere la visualizzazione corrente è perché in base al numero di pagina sto cambiando alcune proprietà di alcuni componenti vista come TextView, immagine ecc Sto usando il codice qui sotto per lo stessonon è in grado di ottenere la vista corrente in Viewpager

ViewPager mPager = (ViewPager) findViewById(R.id.pager); 
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); 
mPager.setAdapter(mPagerAdapter); 
View CurrView; 
OnPageChangeListener pageChangelistener = new OnPageChangeListener() { 
    @Override 
     public void onPageSelected(int pageSelected) { 
      currView = mPager.getChildAt(mPager.getCurrentItem()); 
     myTextView = (TextView)currView.findViewById(R.id.myTextView); 
       loadBookmarkSetting(pageSelected);//do some changes in myTextView properties based on the page number } 
mPager.setOnPageChangeListener(pageChangelistener); 

Ora la problema che sto affrontando dopo aver scrollato 3 pagine e quando arrivo alla quarta pagina, ottengo eccezione nullpointer sulla riga "myTextView = (TextView) currView.findViewById (R.id.myTextView);". Questo è così perché currView è nullo. Qualche idea se sto facendo qualcosa di sbagliato qui. C'è un altro modo per catturare la vista corrente (pagina) in viewpager così come posso fare modifiche sulla vista in base al numero di pagina in cui mi trovo?

+0

Penso che si dovrebbe eseguire il debug qui: 'mPager.getChildAt (mPager.getCurrentItem ()); 'Perché restituisce null? –

+2

Utilizzare questa risposta per ottenere la vista corrente http://stackoverflow.com/a/8638772/527759 – httpdispatch

+0

@ user527759: la sloution nel thread condiviso si applica all'adattatore del cercapersone. Sto comunque utilizzando FragmentStatePagerAdapter. Questo metodo restituirà un oggetto Fragment che non può essere lanciato per visualizzare quindi il codice suggerito non funzionerà – user1938357

risposta

49

È possibile utilizzare il setTag con la vista che si sta restituendo nel metodo instantiateItem (PagerAdapter).

Quindi, quando si istanziano le visualizzazioni in PagerAdapter, il metodo è anche instantiateItem(ViewGroup container, int position)), è necessario utilizzare setTag per la visualizzazione.

Ti piace questa:

view.setTag("myview" + position); 
return view; 

quando è necessario la visualizzazione corrente:

View view = (View) pager.findViewWithTag("myview" + pager.getCurrentItem()); 
+3

Decisione non chiara, perché instantiateItem (...) restituisce Frammento sotto l'interfaccia Oggetto. E possiamo usare Fragemnt.getView() solo dopo aver eseguito la transazione. – ultraon

1

si utilizza questo approccio:

@Nullable 
    public static View getActiveView(@Nonnull final ViewPager viewPager) { 
     final PagerAdapter adapter = viewPager.getAdapter(); 
     if (null == adapter || adapter.getCount() == 0 || viewPager.getChildCount() == 0) { 
      return null; 
     } 

     int position; 
     final int currentPosition = viewPager.getCurrentItem(); 

     for (int i = 0; i < viewPager.getChildCount(); i++) { 
      final View child = viewPager.getChildAt(i); 
      final LayoutParams layoutParams = (LayoutParams) child.getLayoutParams(); 
      if (layoutParams.isDecor) { 
       continue; 
      } 
      final Field positionField; 
      try { 
       positionField = LayoutParams.class.getDeclaredField("position"); 
       positionField.setAccessible(true); 
       position = positionField.getInt(layoutParams); 
      } catch (NoSuchFieldException e) { 
       break; 
      } catch (IllegalAccessException e) { 
       break; 
      } 
      if (position == currentPosition) { 
       return child; 
      } 
     } 
     return null; 
    } 
-1

Il motivo per cui la tua visualizzazione corrente è nullo è perché l'adattatore per cercapersone inizia a distruggere gli oggetti per motivi di efficienza della memoria. Un modo che ho trovato funzionerebbe è quello di sovrascrivere il metodo destroyItem() dell'adattatore cercapersone e salvare i tuoi dati attraverso un elenco o una classe parceable.

0

ho aggiunto uno SparseArray al mio Adapter e aggiungere la vista in instantiateItem() e rimuoverlo in destroyItem()

val views = SparseArray<View>() 

...

override fun instantiateItem(container: ViewGroup, position: Int): Any 
{ 
    //... 

    container.addView(view) 
    views.put(position, view) 
    return view 
} 

override fun destroyItem(container: ViewGroup, position: Int, obj: Any) 
{ 
    views.remove(position) 
    container.removeView(obj as View) 
} 

fun showFooter(currentItem: Int) { 
    views[currentItem].footer_layout.animate().alpha(1f) 
} 

fun hideFooter(currentItem: Int) { 
    views[currentItem].footer_layout.animate().alpha(0f) 
} 

e poi posso chiamare i metodi sull'adattatore:

viewPager.addOnPageChangeListener(object: ViewPager.OnPageChangeListener { 
    override fun onPageScrollStateChanged(state: Int) { 
     when (state) { 
      SCROLL_STATE_IDLE -> adapter.showFooter(viewPager.currentItem) 
      SCROLL_STATE_DRAGGING -> adapter.hideFooter(viewPager.currentItem) 
     } 
    } 

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} 

    override fun onPageSelected(position: Int) {} 

}) 
Problemi correlati