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(), не имеет значения?
Ответы
Ответ 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()