2015-10-14 82 views
0

我知道這已經在這裏討論過很多次了,但我仍然沒有找到解決方案。我正在使用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://stackoverflow.com/questions/11631408/android-fragment-getactivity-有時,返回空 –

回答

0

在活動類中創建碎片靜態字段是一個相當糟糕的想法,android會在配置更改期間重新創建碎片,因此您的靜態實例將被破壞。這對於非保留片段是正確的,但保留片段主要用於保存數據而不是用於構建UI。

我建議您使用getFragmentManager().findFragmentByTagWizardActivity.OnCreate之內重新創建您的嚮導管理器。在初始的addWizardFragment(...);調用中,標記應該存儲在基本活動中 - 您可以很容易地從片段實例中傳遞它們。當然,所有其他狀態應按照Handling Runtime Changes中所述的正常程序保存。

您的客戶在配置更改期間不應該調用addWizardFragment。因此,他們應該寫得相當:

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