FragmentPagerAdapter getItem() 的返回值超过了应有的值
FragmentPagerAdapter getItem() is returning more than it should
我有一个MainActivity
控制四个片段,每个片段都是一个选项卡。当我的 main activity 启动时,我在日志中打印了一行,以显示正在实例化的片段。这是我的 FragmentPagerAdapter:
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
当我的 main activity 启动时,屏幕上会打印以下内容:
Returning new PrearrivalPlan()
Returning new PrimarySurvey()
它似乎在做的是在我选择的选项卡之前加载一个选项卡。由于 PrearrivalPlan 是第一个选项卡,我认为它应该只是 return 一个新的 PrearrivalPlan()
除了它 return 两者。另一个例子,当我点击 Primary Survey 选项卡(第二个选项卡)时,屏幕上会打印以下内容:
Returning new SecondarySurvey() // <- This is the third tab!?
因为 PrimarySurvey 在 activity 第一次启动时已经实例化(见上面的输出),它像以前一样跳到前面并加载了第三个选项卡,即使我只点击了第二个选项卡。
这是我的 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);
}
这是 ViewPager 的预期行为。 ViewPager 始终在内存中前后保留一个选项卡以便显示滑块动画。如果您没有内存中的下一个或上一个选项卡(或片段),则尝试在滑块过渡期间启动片段将导致性能滞后,或者更糟糕的是,您将使滑动片段为空并稍后加载.
ViewPager 还允许您通过 setOffscreenPageLimit() 设置页面偏移限制,这将控制片段数量以将它们保存在内存中。默认情况下,这是 1,这意味着前后一个片段将始终存在于内存中
我有一个MainActivity
控制四个片段,每个片段都是一个选项卡。当我的 main activity 启动时,我在日志中打印了一行,以显示正在实例化的片段。这是我的 FragmentPagerAdapter:
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
当我的 main activity 启动时,屏幕上会打印以下内容:
Returning new PrearrivalPlan()
Returning new PrimarySurvey()
它似乎在做的是在我选择的选项卡之前加载一个选项卡。由于 PrearrivalPlan 是第一个选项卡,我认为它应该只是 return 一个新的 PrearrivalPlan()
除了它 return 两者。另一个例子,当我点击 Primary Survey 选项卡(第二个选项卡)时,屏幕上会打印以下内容:
Returning new SecondarySurvey() // <- This is the third tab!?
因为 PrimarySurvey 在 activity 第一次启动时已经实例化(见上面的输出),它像以前一样跳到前面并加载了第三个选项卡,即使我只点击了第二个选项卡。
这是我的 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);
}
这是 ViewPager 的预期行为。 ViewPager 始终在内存中前后保留一个选项卡以便显示滑块动画。如果您没有内存中的下一个或上一个选项卡(或片段),则尝试在滑块过渡期间启动片段将导致性能滞后,或者更糟糕的是,您将使滑动片段为空并稍后加载.
ViewPager 还允许您通过 setOffscreenPageLimit() 设置页面偏移限制,这将控制片段数量以将它们保存在内存中。默认情况下,这是 1,这意味着前后一个片段将始终存在于内存中