Страницы

Поиск по вопросам

понедельник, 6 мая 2019 г.

Не работает onAttach

Я создал ListFragment (знаю, что есть RecyclerView, просто книгу читаю). В методе onAttach я пытаюсь получить ссылку на активность, чтобы вызывать ее метод. После первого запуска — мое приложение не работало. После 10ти минут раздумий я нашел ошибку! onAttach(Context context) не вызывается, а onAttach(Activity activity) (deprecated) — вызывается! Вот методы:
@Override //РАБОТАЕТ public void onAttach(Activity activity) { super.onAttach(activity); listener = (WorkoutListListener) activity; }
@Override //НЕ РАБОТАЕТ public void onAttach(Context context) { super.onAttach(context); listener = (WorkoutListListener) context; }
Так в чем же разница этих двух методов? Почему устаревший работает, а обычный нет?


Ответ

Подробно на англо-саксонсом тут
Кратко:
ListFragment есть только в пакете android.app и добавляется в активити через FragmentManager вместо SupportFragmentManager. Из-за этого не используется метод onAttach(Context context) на устройствах с API<23, а используется onAttach(Activity activity)
Решением может быть помечание обоих методов соответствующими аннотациями для вызова нужной версии на определённых уровнях API и делегирование продолжения логики в общий для всех API собственный метод, в коем вы уже можете кастовать контекст к активити (помня, что класс итоговой активити разнится в зависимости от уровня API (решение - кастовать к интерфейсу, реализуемому активити):
/* * onAttach(Context) не вызовется до API 23 версии вместо этого будет вызван onAttach(Activity), коий устарел с 23 API * Так что вызовем onAttachToContext */ @TargetApi(23) @Override public void onAttach(Context context) { super.onAttach(context); onAttachToContext(context); }
/* * устарел с 23 API * Так что вызовем onAttachToContext */ @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { onAttachToContext(activity); } }
/* * Вызовется в момент присоединения фрагмента к активити */ protected void onAttachToContext(Context context) { //здесь всегда есть контекст и метод всегда вызовется. //тут можно кастовать контест к активити. //но лучше к реализуемому ею интерфейсу //чтоб не проверять из какого пакета активити в каждом из случаев }

Комментариев нет:

Отправить комментарий