Задать вопрос
@jeezic

Как правильно разбить приложение на Activity и Fragment?

есть приложение с одним активити с NavigationDrawer. при выборе раздела в NavigationDrawer в активити загружается соответствующий фрагмент.
Из одного из фрагментов необходимо вызвать DatePicker(выбор даты из календаря). Календарь достаточно большой, т.е. для его отображения придется либо загрузить новый фрагмент, либо активити, в которой и отобразится календарь.
Выбранная дата из календаря должна вернуться в исходный фрагмент.

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

надеюсь можно понять, какая проблема меня мучает. Нужен "правильный" подход или направление "где почитать" об организации.
  • Вопрос задан
  • 4091 просмотр
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 4
@StanKo
Вообще тут по собственному усмотрению надо делать.
Можно делать фрагменты со стеком, но ведь боковое меню-то останется при этом доступно и юзер сможет туда зайти и логика аппа поломается, т.е. не забыть отключить боковое меню. Однако при системе фрагментов в стеке есть проблема сохранения этого стека при уходе на фон и возврате (запустил календарь, нажал Home типа случайно или тебе как раз в этот момент внезапно позвонили, вернулся в апп - грабли) или при смене ориентации девайса с портрета на альбом (повернул девайс - грабли), потому что в стеке остается только последний фрагмент в таких случаях.
Соответственно хочется перейти к активити и в данном случае лучше запускать активити на результат (startActivityForResult). Соотв. бокового меню не будет вообще, а стек будет нормально сохраняться. Но вот незадача - фрагмент не имеет метода onActivityResult(), он есть у фрагмент-родительской активити, т.е. придется сооружать Вам тут костыли недюжинные чтобы из активити этот результат передать во фрагмент. Ну, гугл на эту тему подскажет.
Ну, или делать как Вы сами и предлагаете - путем именно замещения фрагментов, 1 фрагмент на стеке сохраняется. Но опять же - как транспортировать целевые данные будете в итоге? Через SharedPreferences? Через БД? А как будете знать что это актуальные данные, а не с прошлого выбора остались?
Ответ написан
Комментировать
Xapaxuc
@Xapaxuc
Борода растёт
По моему скромному мнению, для передачи данных из фрагмента в активити и пр. использовать описанный подход слишком неудобно.
Я бы порекомендовал посмотреть библиотеку https://github.com/greenrobot/EventBus. Она решит проблему передачи данных из фрагмента с выбором даты в Activity, где я так понимаю эти данные нужны.
Этот вариант может показаться еще более удобным, учитывая насколько часто приходится сталкиваться с подобного рода задачами при работе с GUI.
Ответ написан
Комментировать
@onepavel
Консультация и разработка мобильных приложений
Фрагмент с DatеPicker кладете поверх фрагмента, куда должен вернуться результат,
с помощью метода add в FragmentTransaction. Один фрагмент подписываете на второй
и ловите дату
Ответ написан
Комментировать
@jeezic Автор вопроса
В общем, поместил я DatePicker в DialogFragment, т.е. он теперь выводится блокируя всю активность, соответственно, и меню слева также заблокировано.

Выяснилось, что OnActivityResult все же можно определить у Fragment и вызвать из другого фрагмента. Я смог вызвать из своего фрагмента фрагмент с DatePicker, передав ему параметры через аргументы, вернув обратно результат в Intent.

Вызов календаря производился так:
DatepickerFragment newFragmentStartDate = 
           DatepickerFragment.newInstance(mYearDate, mMonthDate, mDayDate);
newFragmentStartDate.setTargetFragment(CostEditFragment.this, REQUEST_EDITDATE);
newFragmentStartDate.show(getActivity().getFragmentManager(), "datePicker");


Кнопка "ОК" в календаре с таким кодом:
Intent i = new Intent();
i.putExtra(EXTRA_YEAR, mYear);
i.putExtra(EXTRA_MONTH, mMonth);
i.putExtra(EXTRA_DAY, mDay);
getTargetFragment()
           .onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы