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

Android: как уведомлять активность, когда представления фрагментов готовы?

Я использую API Карт Google V2 в деятельности, где выпадаете навигацию, где карта находится во второй позиции.

Я добавляю карту прагматично:

mMapFragment = supportMapFragment.newInstance();
getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.placeHolder, mMapFragment, TAG_MAP)
        .commit(); 

Я хочу получить файл GoogleMap, так как документация https://developers.google.com/maps/documentation/android/map говорит, что это должно быть сделано с помощью mMapFragment.getMap(), но оно возвращается нуль.

согласно http://developer.android.com/reference/com/google/android/gms/maps/SupportMapFragment.html он возвращает значение null, если фрагмент не прошел через событие жизненного цикла onCreateView.

как я могу знать, когда фрагмент готов?

EDIT: я нашел это Как узнать, что карта готова к использованию при использовании SupportMapFragment?

Overriding onActivityCreated похоже на решение, но тогда мне придется создавать экземпляр фрагмента через конструктор, а не с помощью newInstance(), не имеет значения?

4b9b3361

Ответ 1

Мой предпочтительный метод - использовать обратный вызов для получения сигнала от Fragment. Кроме того, это рекомендуемый метод, предложенный Android при общении с активностью.

Например, добавьте интерфейс в свой Fragment и зарегистрируйте его.

public static interface OnCompleteListener {
    public abstract void onComplete();
}

private OnCompleteListener mListener;

public void onAttach(Context context) {
    super.onAttach(context);
    try {
        this.mListener = (OnCompleteListener)context;
    }
    catch (final ClassCastException e) {
        throw new ClassCastException(context.toString() + " must implement OnCompleteListener");
    }
}

Теперь внедрите этот интерфейс в свою Activity

public class MyActivity extends FragmentActivity implements MyFragment.OnCompleteListener {
    //...

    public void onComplete() {
        // After the fragment completes, it calls this callback.
        // setup the rest of your layout now
        mMapFragment.getMap()
    }
}

Теперь, что бы ни было в вашем Fragment означает, что оно загружено, уведомите свою Activity что оно готово.

@Override
protected void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // create your fragment
    //...

    // signal that you're done and tell the Actvity to call getMap()
    mListener.onComplete();
}

РЕДАКТИРОВАТЬ 2017-12-05 onAttach (Activity Activity) устарела, вместо этого используйте onAttach (Context context). Код выше скорректирован.

Ответ 2

В дополнение к ответ Кирка: поскольку public void onAttach(Activity activity) устарел, вы теперь можете просто использовать:

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

    Activity activity;

    if (context instanceof Activity){

        activity=(Activity) context;

        try {
            this.mListener = (OnCompleteListener)activity;
        } catch (final ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnCompleteListener");
        }
    }
}

Остальное остается неизменным... Можно использовать (Fragment sender) как параметр, хотя и всегда передавать this.

Ответ 3

Я не уверен, что полностью понимаю вашу проблему, но у меня есть аналогичная настройка, где я использую раскрывающееся меню навигации. Вот что для меня работает:

1.) Загрузите фрагмент из xml файла и вызовите setupMapIfNeeded()

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.basicMap);

setUpMapIfNeeded();

Вот XML файл для справки:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/basicMap"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.SupportMapFragment" />

2.) Затем настройте карту (подробности о isGoogleMapsInstalled(), см. этот вопрос)

    private void setUpMapIfNeeded() 
    {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) 
    {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.basicMap)).getMap();
        // Check if we were successful in obtaining the map.
        if(isGoogleMapsInstalled())
        {
            if (mMap != null) 
            {
                mMap.setOnCameraChangeListener(getCameraChangeListener());
                mMap.setInfoWindowAdapter(new MyCustomInfoWindowAdapter(this));
            }
        }
        else
        {
            MapConstants.showDialogWithTextAndButton(this, R.string.installGoogleMaps, R.string.install, false, getGoogleMapsListener());
        }
    }
    }

3.) Убедитесь, что вы также вызываете setUpMapIfNeeded() из onResume():

public void onResume()
{
    super.onResume();

    setUpMapIfNeeded();
}

Ответ 4

Если вы хотите сделать это без какого-либо слушателя:

Добавить фрагмент с тегом

 supportFragmentManager
                .beginTransaction()
                .add(R.id.pagerContainer, UniversalWebViewFragment.newInstance(UniversalWebViewFragment.YOUTUBE_SERACH_URL+"HD trailers"), 
                "UniversalWebView")
                .disallowAddToBackStack()
                .commit()

Создайте открытый метод в классе Hosting Activity, который вы хотите вызывать после загрузки фрагмента. Здесь я перезваниваю метод моего фрагмента, например

public fun loadURL() {
        val webViewFragment = supportFragmentManager
                              .findFragmentByTag("UniversalWebView") 
                               as UniversalWebViewFragment

        webViewFragment.searchOnYoutube("Crysis Warhead")
    }

Теперь внутри метода onViewCreated вашего фрагмента вы можете просто вызвать этот публичный метод активности Host следующим образом:

    (activity as HomeActivity ).loadURL()