保持对象在屏幕上旋转?
问题描述:
我知道这已经在这里讨论过很多次了,但我仍然没有找到解决方案。我正在使用ViewPager为Android创建“向导”组件,其中包含一些片段(有多少片段取决于将使用此扩展的开发人员),并且我需要保存向导状态。我发现的唯一方法是强制开发人员在使用此扩展时声明静态片段,但我真的不喜欢这样(因为它对开发人员来说更复杂,我希望尽可能使用它)。保持对象在屏幕上旋转?
我的扩展类:
public class WizardActivity extends AppCompatActivity {
private WizardAdapter wizardAdapter;
private WizardPager wizardPager;
private Button buttonNext;
private Button buttonPrevious;
private int wizardPagerID;
private int buttonNextID;
private int buttonPreviousID;
private int layoutID;
private boolean swipeEnabled;
public WizardActivity(int layoutID, int buttonNext, int buttonPrevious, int wizardPager, boolean swipeEnabled) {
super();
this.wizardAdapter = new WizardAdapter(getSupportFragmentManager());
this.wizardPagerID = wizardPager;
this.buttonNextID = buttonNext;
this.buttonPreviousID = buttonPrevious;
this.layoutID = layoutID;
this.swipeEnabled = swipeEnabled;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layoutID);
wizardPager = (WizardPager) findViewById(wizardPagerID);
buttonNext = (Button) findViewById(buttonNextID);
buttonPrevious = (Button) findViewById(buttonPreviousID);
wizardPager.setAdapter(wizardAdapter);
wizardPager.setSwipeEnabled(swipeEnabled);
buttonNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onNextButton(wizardPager.getCurrentItem())) {
wizardPager.showNext();
refreshButtons();
}
}
});
buttonPrevious.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onPreviousButton(wizardPager.getCurrentItem())) {
wizardPager.showPrevious();
refreshButtons();
}
}
});
if(savedInstanceState != null) {
wizardPager.setCurrentItem(savedInstanceState.getInt("page", 0));
}
refreshButtons();
}
@Override
public void onBackPressed() {
if (wizardPager.getCurrentItem() == 0) {
super.onBackPressed();
} else {
wizardPager.showPrevious();
refreshButtons();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("page", wizardPager.getCurrentItem());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
refreshButtons();
}
public WizardPager getWizardPager() { return wizardPager; }
public WizardAdapter getWizardAdapter() { return wizardAdapter; }
public Button getButtonNext() { return buttonNext; }
public Button getButtonPrevious() { return buttonPrevious; }
public void addWizardFragment(WizardFragment fragment) { wizardAdapter.addFragment(fragment); }
public boolean showNextFragment() {
return onNextButton(wizardPager.getCurrentItem()) && wizardPager.showNext();
}
public boolean showPreviousFragment() {
return onPreviousButton(wizardPager.getCurrentItem()) && wizardPager.showPrevious();
}
public void refreshButtons() {
WizardFragment currentFragment = wizardAdapter.getItem(wizardPager.getCurrentItem());
buttonPrevious.setEnabled(currentFragment.isPreviousEnabled());
buttonPrevious.setText(currentFragment.getPreviousText());
buttonNext.setEnabled(currentFragment.isNextEnabled());
buttonNext.setText(currentFragment.getNextText());
}
public boolean onNextButton(int currentItem) {
return true;
}
public boolean onPreviousButton(int currentItem) {
return true;
}
}
其他开发商的类可以是这样的:
public class SetupActivity extends WizardActivity {
private static SetupFragment setupFragment = new SetupFragment();
private static SetupLicenseFragment setupLicenseFragment = new SetupLicenseFragment();
private static SetupLoginFragment setupLoginFragment = new SetupLoginFragment();
public SetupActivity() {
super(R.layout.activity_setup, R.id.button2, R.id.button3, R.id.pager, false);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
String previousText = getString(R.string.setup_button_previous);
String nextText = getString(R.string.setup_button_next);
String finishText = getString(R.string.setup_button_finish);
setupFragment.setupFragment(previousText, nextText, false, true);
setupLicenseFragment.setupFragment(previousText, nextText, true, false);
setupLoginFragment.setupFragment(previousText, finishText, true, false);
addWizardFragment(setupFragment);
addWizardFragment(setupLicenseFragment);
addWizardFragment(setupLoginFragment);
super.onCreate(savedInstanceState);
}
@Override
public boolean onNextButton(int currentItem) {
if(currentItem == 2) {
Intent intent = new Intent(SetupActivity.this, MainActivity.class);
startActivity(intent);
finish();
return false;
}
return super.onNextButton(currentItem);
}
}
(WizardAdapter包含WizardFragments的ArrayList)
有没有办法救添加的片段由其他开发者提供,而不会让开发者更难?
答
在活动类中创建碎片静态字段是一个相当糟糕的想法,android会在配置更改期间重新创建碎片,因此您的静态实例将被破坏。这对于非保留片段是正确的,但保留片段主要用于保存数据而不是用于构建UI。
我建议您使用getFragmentManager().findFragmentByTag
在WizardActivity.OnCreate
之内重新创建您的向导管理器。在初始的addWizardFragment(...);
调用中,标记应该存储在基本活动中 - 您可以很容易地从片段实例中传递它们。当然,所有其他状态应按照Handling Runtime Changes中所述的正常程序保存。
您的客户在配置更改期间不应该调用addWizardFragment。因此,他们应该写得相当:
if (savedInstanceState == null) {
addWizardFragment(setupFragment);
addWizardFragment(setupLicenseFragment);
addWizardFragment(setupLoginFragment);
}
也许你应该从SetupActivty通过整个适配器和活动后重新填充碎片,就这个一看http://*.com/questions/11631408/android-fragment-getactivity-有时,返回空 –