【问题标题】:Android: how to notify Activity when Fragments views are ready?Android:当片段视图准备好时如何通知 Activity?
【发布时间】:2013-02-21 10:17:19
【问题描述】:

我在地图位于第二个位置的下拉导航活动中使用 Google Maps API 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() 完成,但它返回 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() 来实例化片段,这有什么区别吗?

【问题讨论】:

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


    【解决方案1】:

    我首选的方法是使用回调从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();
    }
    

    EDIT 2017-12-05 onAttach(Activity activity) 是 deprecated,请改用 onAttach(Context context)。以上代码已调整。

    【讨论】:

    • 只是评论 onAttach(Activity activity) 已被弃用
    • Ewoks,那么,应该改用哪种方法?
    【解决方案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

    【讨论】:

      【解决方案3】:

      如果你想在没有任何监听器的情况下这样做:

      使用 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()
      

      【讨论】:

        【解决方案4】:

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

        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();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-22
          • 1970-01-01
          相关资源
          最近更新 更多