保持对象在屏幕上旋转?

问题描述:

我知道这已经在这里讨论过很多次了,但我仍然没有找到解决方案。我正在使用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)

有没有办法救添加的片段由其他开发者提供,而不会让开发者更难?

+0

也许你应该从SetupActivty通过整个适配器和活动后重新填充碎片,就这个一看http://*.com/questions/11631408/android-fragment-getactivity-有时,返回空 –

在活动类中创建碎片静态字段是一个相当糟糕的想法,android会在配置更改期间重新创建碎片,因此您的静态实例将被破坏。这对于非保留片段是正确的,但保留片段主要用于保存数据而不是用于构建UI。

我建议您使用getFragmentManager().findFragmentByTagWizardActivity.OnCreate之内重新创建您的向导管理器。在初始的addWizardFragment(...);调用中,标记应该存储在基本活动中 - 您可以很容易地从片段实例中传递它们。当然,所有其他状态应按照Handling Runtime Changes中所述的正常程序保存。

您的客户在配置更改期间不应该调用addWizardFragment。因此,他们应该写得相当:

if (savedInstanceState == null) { 
    addWizardFragment(setupFragment); 
    addWizardFragment(setupLicenseFragment); 
    addWizardFragment(setupLoginFragment); 
}