Android:如何在Fragments视图准备好后通知Activity?

时间:2013-02-21 10:17:20

标签: android android-fragments google-maps-android-api-2

我正在使用Google Maps API V2进行活动,该地图位于第二个位置的下拉导航栏中。

我正在实际添加地图,如:

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

我希望获得GoogleMap ovject,因为文档https://developers.google.com/maps/documentation/android/map表示应该使用mMapFragment.getMap(),但它会返回null。

根据http://developer.android.com/reference/com/google/android/gms/maps/SupportMapFragment.html 如果Fragment尚未通过onCreateView生命周期事件,则返回null。

我怎么知道片段什么时候准备就绪?

编辑:我发现了How do I know the map is ready to get used when using the SupportMapFragment?

覆盖onActivityCreated似乎是一个解决方案,但是我必须通过构造函数实例化片段而不是使用newInstance(),它会有什么不同吗?

4 个答案:

答案 0 :(得分:41)

我首选的方法是使用回调来获取Fragment的信号。此外,这是Android在Communicating with the Activity

提出的推荐方法

对于您的示例,请在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(活动活动)是deprecated,使用onAttach(上下文上下文)代替。以上代码经过调整。

答案 1 :(得分:2)

Kirk's answer之外:由于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

答案 2 :(得分:0)

我不确定我是否完全理解您的问题,但我有一个类似的设置,我正在使用导航下拉菜单。这对我有用:

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()的详细信息,请参阅this question

    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.确保你也从onResume()调用setUpMapIfNeeded():

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

    setUpMapIfNeeded();
}

答案 3 :(得分:0)

如果您想在没有任何侦听器的情况下执行此操作:

添加带有 TAG

的片段
 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()