FragmentViewPagerAdapter 在屏幕旋转后不调用 getItem
FragmentViewPagerAdapter not calling getItem after screen rotation
我在这个 activity 中有一个自定义 viewPagerAdapter,当 activity 第一次启动时(当主 activity 以意图启动它时)寻呼机正确显示片段,但是当我旋转设备时,配方是从 savedInstantState 中获取的,并且适配器已启动,但是没有显示片段,也没有调用 getItem 方法!
这是 Activity 的代码:
包裹 com.ameer.bake.activities;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.ViewGroup;
import com.ameer.bake.Constants;
import com.ameer.bake.fragments.IngredientsFragment;
import com.ameer.bake.fragments.StepDetailsFragment;
import com.ameer.bake.fragments.StepsFragment;
import com.ameer.bake.R;
import com.ameer.bake.models.Recipe;
import com.ameer.bake.models.Step;
import com.google.gson.Gson;
import com.ogaclejapan.smarttablayout.SmartTabLayout;
public class DetailsActivity extends AppCompatActivity implements StepsFragment.StepCallback{
private Recipe recipe;
private IngredientsFragment ingredientsFragment;
private StepsFragment stepsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState != null){
recipe = new Gson().fromJson(savedInstanceState.getString(Constants.RECIPE), Recipe.class);
setupViewPager();
} else if (getIntent().hasExtra(Constants.CURRENT_RECIPE_KEY) ) {
Gson gson = new Gson();
recipe = gson.fromJson(getIntent().getStringExtra(Constants.CURRENT_RECIPE_KEY), Recipe.class);
setTitle(recipe.getName());
setupViewPager();
}
}
@Override
public void onStepClicked(Step step) {
Intent intent = new Intent(DetailsActivity.this, StepActivity.class);
intent.putExtra(Constants.STEP_KEY, new Gson().toJson(step));
startActivity(intent);
}
private class RecipePagerAdapter extends FragmentPagerAdapter {
private static final int NUM_ITEMS = 2;
private final String[] titles = new String[]{
getString(R.string.ingredients), getString(R.string.steps)};
private RecipePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
if (ingredientsFragment == null && stepsFragment == null) {
ingredientsFragment = new IngredientsFragment();
ingredientsFragment.setIngredients(recipe.getIngredients());
stepsFragment = new StepsFragment();
stepsFragment.setSteps(recipe.getSteps());
stepsFragment.setCallback(DetailsActivity.this);
}
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ingredientsFragment;
case 1:
return stepsFragment;
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home){
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(Constants.RECIPE, new Gson().toJson(recipe));
super.onSaveInstanceState(savedInstanceState);
}
private void setupViewPager(){
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
FragmentPagerAdapter pagerAdapter = new RecipePagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(pagerAdapter);
SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpager_tab);
viewPagerTab.setViewPager(vpPager);
}
}
切换到 FragmentStatePagerAdapter 而不是使用 FragmentPagerAdapter。还使用 getChildFragmentManager() 而不是 getSupportFragmentManager()
解决方案正如 Pedro Varela 在评论中提到的那样:
"Hope this works. Add setRetainInstance(true); in onCreate of your internal fragments of the view pager "控制片段实例是否在 Activity 重新创建(例如从配置更改)中保留。这只能用于不在返回堆栈中的片段。如果设置,片段生命周期将在重新创建 activity 时略有不同""
谢谢
我在这个 activity 中有一个自定义 viewPagerAdapter,当 activity 第一次启动时(当主 activity 以意图启动它时)寻呼机正确显示片段,但是当我旋转设备时,配方是从 savedInstantState 中获取的,并且适配器已启动,但是没有显示片段,也没有调用 getItem 方法!
这是 Activity 的代码: 包裹 com.ameer.bake.activities;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.ViewGroup;
import com.ameer.bake.Constants;
import com.ameer.bake.fragments.IngredientsFragment;
import com.ameer.bake.fragments.StepDetailsFragment;
import com.ameer.bake.fragments.StepsFragment;
import com.ameer.bake.R;
import com.ameer.bake.models.Recipe;
import com.ameer.bake.models.Step;
import com.google.gson.Gson;
import com.ogaclejapan.smarttablayout.SmartTabLayout;
public class DetailsActivity extends AppCompatActivity implements StepsFragment.StepCallback{
private Recipe recipe;
private IngredientsFragment ingredientsFragment;
private StepsFragment stepsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState != null){
recipe = new Gson().fromJson(savedInstanceState.getString(Constants.RECIPE), Recipe.class);
setupViewPager();
} else if (getIntent().hasExtra(Constants.CURRENT_RECIPE_KEY) ) {
Gson gson = new Gson();
recipe = gson.fromJson(getIntent().getStringExtra(Constants.CURRENT_RECIPE_KEY), Recipe.class);
setTitle(recipe.getName());
setupViewPager();
}
}
@Override
public void onStepClicked(Step step) {
Intent intent = new Intent(DetailsActivity.this, StepActivity.class);
intent.putExtra(Constants.STEP_KEY, new Gson().toJson(step));
startActivity(intent);
}
private class RecipePagerAdapter extends FragmentPagerAdapter {
private static final int NUM_ITEMS = 2;
private final String[] titles = new String[]{
getString(R.string.ingredients), getString(R.string.steps)};
private RecipePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
if (ingredientsFragment == null && stepsFragment == null) {
ingredientsFragment = new IngredientsFragment();
ingredientsFragment.setIngredients(recipe.getIngredients());
stepsFragment = new StepsFragment();
stepsFragment.setSteps(recipe.getSteps());
stepsFragment.setCallback(DetailsActivity.this);
}
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ingredientsFragment;
case 1:
return stepsFragment;
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home){
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(Constants.RECIPE, new Gson().toJson(recipe));
super.onSaveInstanceState(savedInstanceState);
}
private void setupViewPager(){
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
FragmentPagerAdapter pagerAdapter = new RecipePagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(pagerAdapter);
SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpager_tab);
viewPagerTab.setViewPager(vpPager);
}
}
切换到 FragmentStatePagerAdapter 而不是使用 FragmentPagerAdapter。还使用 getChildFragmentManager() 而不是 getSupportFragmentManager()
解决方案正如 Pedro Varela 在评论中提到的那样: "Hope this works. Add setRetainInstance(true); in onCreate of your internal fragments of the view pager "控制片段实例是否在 Activity 重新创建(例如从配置更改)中保留。这只能用于不在返回堆栈中的片段。如果设置,片段生命周期将在重新创建 activity 时略有不同"" 谢谢