Подтвердить что ты не робот

OnAttach() не вызывается в фрагменте

Мой фрагмент не вызывает метод onAttach(context), когда он запускается с AppCompatActivity.

Создание фрагмента в XML:

<fragment
    android:id="@+id/toolbar"
    class="package.MainToolbarFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:layout="@layout/fragment_main_toolbar" />

Но если я протягиваю его из support.v4.Fragment, onAttach(context) call!

В чем может быть проблема?

Конечно, я могу расширить все фрагменты из v4.Fragment, но я не хочу этого. Это плохая практика? Также выполните проект min sdk 14.

4b9b3361

Ответ 1

Он не вызван, потому что этот метод был добавлен в API 23. Если вы запустите приложение на устройстве с API 23 (зефир), тогда будет вызван onAttach(Context). На всех предыдущих версиях Android onAttach(Activity) будет вызываться.

http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity)

Фрагмент поддержки библиотек не зависит от платформы. Следовательно, он работает во всех версиях API.

Ответ 2

Пока Google хочет, чтобы мы прекратили использование устаревших API

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    ...

Является настолько новым, что его широко не называют. Вам также необходимо реализовать

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    ...

Для меня они идентичны, но мне нравится KISS, а введение другой библиотеки поддержки, как правило, удваивает мой apk примерно до 1000 кб. Я только вчера обновил свой SDK.

Причина того, что типы не взаимозаменяемы здесь, как и во многих случаях, заключается в том, что метод, принимающий Activity, все равно будет вызываться, когда предоставляется Activity, поскольку они являются общедоступными, а Activity - более специализированный, чем (в качестве подкласса) Context, будет иметь приоритет.

Ответ 3

В дополнение к вышеупомянутым комментариям, я считаю важным отметить, что если вы пытаетесь использовать onAttach() для обновления данных, содержащихся внутри фрагмента, из родительской активности, можно столкнуться с проблемами, когда сбор переменная внутри Activity является пустой или пустой, когда фрагмент завышен. В какой-то момент жизненного цикла вашей деятельности ваша модель данных может измениться и должна быть обновлена ​​внутри фрагмента. Вы можете попытаться получить ссылку на уже завышенный фрагмент, но обнаружите, что при выполнении кода, который onAttach() никогда не срабатывает, даже при использовании переопределения, содержащего объект Контекст или Активность.

Если вы пытаетесь создать слушатель для фрагмента и инициализировать прослушиватель из метода обратного вызова onAttach(), onAttach() не будет срабатывать, если вы не предоставите параметр тега, как показано ниже, при добавлении фрагмента в Activity:

// in the Activity
getFragmentManager().beginTransaction()
    .add(
        R.id.fragmentContainer,
        CustomFragment.newInstance(customDataSource),
        CustomFragment.TAG // Must be passed in for the code below to work
    ).commit();


// Getting a reference to the fragment later on (say to update your data model inside the fragment (in onActivityResult())

CustomFragment fragmentDelegate = (CustomFragment) getFragmentManager().findFragmentByTag(CustomFragment.TAG);
fragmentListener.updateDataSource(customDataSource);

Ответ 4

Если вы еще не используете фрагмент поддержки, чтобы получить обратную совместимость, вы можете сделать что-то вроде ниже.

 @Override
public void onAttach(Activity activity) //For backward compatibility
{
    super.onAttach(activity);
    onContextAttached(activity);
}

@Override
public void onAttach(Context context)
{
    super.onAttach(context);
    onContextAttached(context);
}

private void onContextAttached(Context context)
{
// Common code here
}

Здесь мы просто пересылаем вызов одному методу, чтобы он работал на всех платформах.

Но убедитесь, что вы начали обновлять свой код для использования вспомогательного фрагмента, так как класс Fragment по умолчанию устарел из API 28