2015-08-03 4 views
1

У меня есть MainActivity, который управляет четырьмя фрагментами, каждый из которых является вкладкой. Когда начнется мое основное действие, у меня есть строка, печатаемая в журнале, чтобы показать мне, какой экземпляр создается. Вот мой FragmentPagerAdapter:FragmentPagerAdapter getItem() возвращается больше, чем он должен

public class TabsPagerAdapter extends FragmentPagerAdapter { 

public TabsPagerAdapter(FragmentManager fm) { 
    super(fm); 
} 

@Override 
public Fragment getItem(int index) { 

    switch (index) { 
     case 0: 
      System.out.println("Returning new PrearrivalPlan()"); 
      return new PrearrivalPlan(); 
     case 1: 
      System.out.println("Returning new PrimarySurvey()"); 
      return new PrimarySurvey(); 
     case 2: 
      System.out.println("Returning new SecondarySurvey()"); 
      return new SecondarySurvey(); 
     case 3: 
      System.out.println("Returning new PrepareForTravel()"); 
      return new PrepareForTravel(); 
    } 

    return null; 
} 

@Override 
public int getCount() { 
    // get item count - equal to number of tabs 
    return 4; 
} 

} 

Панель вкладок имеет следующие параметры в порядке:

Prearrival Plan | Primary Survey | Secondary Survey | Prepare for Travel

Когда начинается моя основная деятельность, выводится на экран следующее:

Returning new PrearrivalPlan() Returning new PrimarySurvey()

Возможно, что-то происходит, когда загружается одна вкладка впереди той, которую я выбрал. Поскольку PrearrivalPlan - первая вкладка, я думаю, что она должна просто вернуть новый PrearrivalPlan(), за исключением того, что он возвращает оба. Другой пример, когда я нажимаю на начальной вкладке Survey (вторая вкладка), следующий выводятся на экран:

Returning new SecondarySurvey() // <- This is the third tab!?

Поскольку PrimarySurvey уже инстанцирован когда активность первого начала (см выхода выше), он прыгнул впереди, как и раньше, и загрузил третью вкладку, хотя я только нажимал на вторую.

Вот мой MainActivity:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener { 

private CustomViewPager viewPager; 
private TabsPagerAdapter mAdapter; 
private ActionBar actionBar; 

private String[] tabTitles = {"Pre-arrival Plan", "Primary Survey", "Secondary Survey", "Prepare for Travel"}; 

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    viewPager = (CustomViewPager) findViewById(R.id.pager); 
    actionBar = getActionBar(); 
    mAdapter = new TabsPagerAdapter(getSupportFragmentManager()); 

    viewPager.setAdapter(mAdapter); 
    viewPager.setPagingEnabled(false); 

    actionBar.setHomeButtonEnabled(true); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 


    viewPager.setOnPageChangeListener(new CustomViewPager.OnPageChangeListener() { 


     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

     } 

     @Override 
     public void onPageSelected(int position) { 
      actionBar.setSelectedNavigationItem(position); 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 

     } 

    }); 

    // Remove Android icon from Action Bar 
    getActionBar().setIcon(new ColorDrawable(getResources().getColor(android.R.color.transparent))); 
    getActionBar().setDisplayShowHomeEnabled(false); 

    // Add tabs to Action Bar 
    for (String tab_name : tabTitles) { 
     actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this)); 
    } 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

public void updateTabTitles(int tabNumber, int checkBoxesRemaining) { 
    String text = tabTitles[tabNumber] + " \n    (" + checkBoxesRemaining + ")"; 
    actionBar.getTabAt(tabNumber).setText(text); 
} 

@Override 
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
    viewPager.setCurrentItem(tab.getPosition()); 
} 

@Override 
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { 

} 

@Override 
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { 

} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      Intent intent = new Intent(this, MainMenu.class); 
      startActivity(intent); 
      return true; 
     case R.id.complete: 
      DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        switch (which){ 
         case DialogInterface.BUTTON_POSITIVE: 
          goToReport(); 
          break; 
         case DialogInterface.BUTTON_NEGATIVE: 
          //No button clicked 
          break; 
        } 
       } 
      }; 
      AlertDialog.Builder builder = new AlertDialog.Builder(this); 
      builder.setMessage("Are you sure you want to complete the checklist?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show(); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
    } 
} 

public void goToReport() { 
    Intent intent = new Intent(this, Report.class); 
    startActivity(intent); 
} 
+0

* FragmentPagerAdapter getItem() возвращается больше, чем нужно * нет, это не так ... это до PagerAdapter для вызова getItem ... если вы беспокоитесь об этом, тогда вы не должны его использовать (возможно, вам нужно найти какой-либо элемент управления мастером) – Selvin

+0

@Selvin Я начинающий, когда речь идет о вкладках и даже разработке Android в целом, так что, может быть, я просто недоразумение. – Brejuro

ответ

2

Это ожидаемое поведение ViewPager. ViewPager всегда держит одну вкладку впереди и сзади в памяти , чтобы показать анимацию слайдера. Если у вас нет следующей или предыдущей вкладки (или фрагмента) в памяти, попытка инициировать фрагмент во время перехода слайдера вызовет отставание в производительности или, что хуже, у вас будет скользящий фрагмент, который будет пустым и загрузится позже ,

ViewPager также позволяет установить предел смещения страницы через setOffscreenPageLimit(), который будет управлять фрагментом количества, чтобы сохранить их в памяти. По умолчанию это 1, что означает, что один фрагмент впереди и позади всегда будет там в памяти

+0

Исключительно полезный и информативный комментарий: 'setOffscreenPageLimit()' исправил проблемы, которые у меня были с вкладками, действующими по-другому, чем я ожидал, за пределами того, что я разместил выше. Большое спасибо! – Brejuro

Смежные вопросы