Android: how to notify Activity when Fragments views are ready?

前端 未结 4 855
陌清茗
陌清茗 2020-12-14 07:34

I\'m using Google Maps API V2 in an activity wih drop down navigation where the map is on the second position.

I\'m adding the map pragmatically like:



        
相关标签:
4条回答
  • 2020-12-14 07:38

    I'm not sure I'm completely understanding your issue, but I have a similar setup where I'm using a navigation drop down menu. Here's what works for me:

    1.) Load the fragment from an xml file and call setupMapIfNeeded()

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

    Here is the xml file for reference:

    <?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.) Then setup the map (for details of isGoogleMapsInstalled(), see 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.) Make sure you also call setUpMapIfNeeded() from onResume():

    public void onResume()
    {
        super.onResume();
    
        setUpMapIfNeeded();
    }
    
    0 讨论(0)
  • 2020-12-14 07:53

    If you want to do it without any listener:

    Add Fragment with a TAG

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

    Create a public method in Hosting Activity class which you want to call after fragment is loaded. Here I am calling back a method of my fragment for example

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

    Now inside onViewCreated Method of your fragment you can simply call that public method of Host activity like this:

        (activity as HomeActivity ).loadURL()
    
    0 讨论(0)
  • 2020-12-14 07:54

    My preferred method is to use a callback to get a signal from a Fragment. Also, this is the recommended method proposed by Android at Communicating with the Activity

    For your example, in your Fragment, add an interface and register it.

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

    Now implement this interface in your 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()
        }
    }
    

    Now, whatever in your Fragment signifies that it's loaded, notify your Activity that it's ready.

    @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) is deprecated, use onAttach(Context context) instead. Code above adjusted.

    0 讨论(0)
  • 2020-12-14 07:59

    In addition to Kirk's answer: since public void onAttach(Activity activity) is deprecated you can now simply use:

    @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");
            }
        }
    }
    

    The rest remains the same... One might want to use (Fragment sender) as a parameter though and always pass this.

    0 讨论(0)
提交回复
热议问题