2015-10-14 2 views
0

Я знаю, что это обсуждалось здесь много раз, но я до сих пор не нашел для этого решения. Я создаю компонент «wizard» для Android, используя ViewPager, который содержит некоторые фрагменты (сколько фрагментов зависит от разработчика, который будет использовать это расширение), и мне нужно сохранить состояние мастера. Единственным способом, который я нашел, было заставить разработчиков объявлять статические фрагменты при использовании этого расширения, но мне это действительно не нравится (потому что это сложнее для разработчиков, и я хочу сделать его максимально простым в использовании).Держите объект на экране вращения?

Мой класс расширения:

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 содержит ArrayList из WizardFragments)

Есть ли способ, чтобы сохранить фрагменты добавлены другими разработчиками, не создавая сложностей для разработчиков?

+0

Вероятно, вы должны пройти весь адаптер от SetupActivty и заполнения фрагментов после активности воссоздан, посмотрите на это http://stackoverflow.com/questions/11631408/android-fragment-getactivity- когда-то возвраты-нуль –

ответ

0

Создание фрагментов статических полей внутри вашего класса активности - довольно плохая идея, андроид будет воссоздавать фрагмент во время изменений конфигурации, поэтому ваши статические экземпляры будут уничтожены. Это справедливо для не сохранившихся фрагментов, но сохраненные фрагменты полезны главным образом для хранения данных, а не для создания пользовательских интерфейсов.

Я предлагаю вам заново создать своего менеджера-менеджера внутри WizardActivity.OnCreate с помощью getFragmentManager().findFragmentByTag. Теги должны храниться во время начальных вызовов addWizardFragment(...); из базовой активности - вы можете легко получить их из переданных в экземпляре фрагмента. Конечно, все остальные состояния должны быть сохранены с использованием обычной процедуры, как описано в Handling Runtime Changes.

Ваши клиенты не должны вызывать addWizardFragment во время изменений конфигурации. Таким образом, они должны написать вместо:

if (savedInstanceState == null) { 
    addWizardFragment(setupFragment); 
    addWizardFragment(setupLicenseFragment); 
    addWizardFragment(setupLoginFragment); 
} 
Смежные вопросы