Pull to refresh

Comments 16

Спасибо за статью!
Метод onSaveInstanceState имеет множество особенностей применительно к фрагментам и особенно к вложенным фрагментам.
Для себя выбрал вариант с сохранением состояния внутри аргументов фрагмента.
А что думаете насчет отказа от использования фрагментов в пользу одной активити и обычных вьюх?
setRetainInstance(true) — прекрасный метод. Только стоит упомянуть, что его нельзя использовать в паре с Loader
В статье не упомянуто о том, что setRetainInstance(true) не будет работать для фрагментов, находящихся в back stack (тыц). А это — совсем не маловажный момент.
Не надо во фрагменте держать медиаплеер. Вынесите его в сервис.
Хоть это и не совсем относится к статье.
А почему на второй картинке в столбце «After device turn» «NEW Fragment»? Полагаю должен быть старый фрагмент…
я дико извиняюсь, но вы исправили ПЕРВУЮ картинку, а надо было вторую...
Главное при использовании setRetainInstance(true) — занулять все ссылки на любые View в onDestroyView(). Иначе старая Activity утечёт на некоторое время.
Ну и не надо забывать, что сохранять состояние в Bundle необходимо в любом случае. Иначе краткое переключение на какое-нибудь тяжёлое приложение (например, браузер) может запросто уничтожить состояние UI, что очень неприятно для пользователя.
Насколько я помню setRetainInstance(true) рекомендуется использовать в крайних случаях (или для фрагментов которые не имею UI). А вот проблема с прерыванием воспроизведения при перевороте решается с помощью Service.
Пожалуйста, в перспективе еще несколько статей раскрывающих с той или иной стороны реализацию и использование фрагментов.
Использую RetainInstance фрагменты только для сохранения объектов, которые должны пережить разворот экрана, например момент авторизации пользователя, заливка файла и прочее.
Сохраняемый объект при этом должен реализовывать паттерн Observer and Observable.
Кому интересно, пример:
ModelStorage.java
public class ModelStorage extends Fragment {
    public static final String TAG = ModelStorage.class.getCanonicalName();
    private CallbackModel model = new CallbackModel();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    public CallbackModel getCallbackModel(){
        return model;
    }


CallbackModel.java
public class CallbackModel {
    private CallbackObservable observable = new CallbackObservable();
    ...
   public void runTask() {
   // some work
   .... 
    observable.notifyOnSucces();
   }

    public void registerObserver(CallbackObserver observer) {
        observable.registerObserver(observer);
    }

    public void unregisterObserver(CallbackObserver observer) {
        observable.unregisterObserver(observer);
    }

    public interface CallbackObserver {
        void onSucces();
        void onFail();
    }

    private class CallbackObservable extends Observable<CallbackObserver> {

        public void notifyOnSucces() {
            for (CallbackObserver observer : mObservers) {
                observer.onSucces();
            }
        }

        public void notifyOnFail() {
            for (CallbackObserver observer : mObservers) {
                observer.onFail();
            }
        }
    }

}


Пример использования
public class SomeFragment extends BaseFragment implements CallbackModel.CallbackObserver {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final ModelStorage storage = (ModelStorage) getActivity()
                .getSupportFragmentManager()
                .findFragmentByTag(ModelStorage.TAG);

        if (storage != null) {
            model = storage.getCallbackModel();
        } else {
            final ModelStorage newStorage = new ModelStorage();
            getActivity()
                    .getSupportFragmentManager()
                    .beginTransaction()
                    .add(newStorage, ModelStorage.TAG)
                    .commit();
        }
        model.registerObserver(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        model.unregisterObserver(this);
    }

    @Override
    public void onSuccess() {

    }

    @Override
    public void onFail() {

    }

}

Иногда для сохранения объекта используют экземпляр приложения, т.е. выносят на уровень выше и фрагмента, и активности.
Это неудобно. Экземпляр приложения один, а таких фрагментом может быть много.
Only those users with full accounts are able to leave comments. Log in, please.