Search code examples
javaandroidgoogle-mapsandroid-fragmentssupportmapfragment

Alternative to using getMap() in SupportMapFragment Java Android Studio


I am currently working on an app for my martial arts organization. I want to have a fragment that uses SupportMapFragment which displays the different locations of each martial arts dojo within my state. I currently have a Navigation Drawer set up, with a tab titled "Locations". I am following along with how the guys at Tutsplus created their Zoo application and included a map within that application. The code that I am looking at is found here. In their code and tutorial on Youtube, they use getMap().animateCamera... in order to control the camera and get the map to work. I already know that getMap() has been removed from Android, and that getMapAsync(this) is a better option, however I'm struggling with figuring out how to work getMapAsync()into my code with how my code is currently set up, and I could use some assistance. I've looked through all of Google's documentation and read through multiple threads on this site, but I haven't had much luck. Here is my code below for my LocationFragment.java:

public class LocationFragment extends SupportMapFragment {

    public static LocationFragment getInstance() {
        LocationFragment fragment = new LocationFragment();

        return fragment;
    }
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

        super.onViewCreated(view, savedInstanceState);

        CameraPosition position = CameraPosition.builder()
                .target(new LatLng(42.921966,  -85.718533))
                .zoom( 16f )
                .bearing( 0.0f )
                .tilt( 0.0f )
                .build();

        getMap().animateCamera(CameraUpdateFactory.newCameraPosition(position), null);
        getMap().setMapType(GoogleMap.MAP_TYPE_HYBRID);
        getMap().setTrafficEnabled(true);

        getMap().getUiSettings().setZoomControlsEnabled(true);

        MarkerOptions options = new MarkerOptions().position(new LatLng(42.921966,  -85.718533));
        options.title("KFCOM");
        options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
        getMap().addMarker(options);

        getMap().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                marker.showInfoWindow();
                return true;
            }
        });

        RestAdapter adapter = new RestAdapter.Builder()
                .setEndpoint("https://gist.githubusercontent.com/anonymous/101ffbf7e1aed60b7caf7d3d5418bfde/raw/43b5d1fa6862fd1dce84044821cdf1a9d48b6ca2")
                .build();
        PinsApiInterface pinsApiInterface = adapter.create(PinsApiInterface.class );

        pinsApiInterface.getStreams(new Callback<List<Pin>>() {
            @Override
            public void onResponse(Call<List<Pin>> pins, Response<List<Pin>> response) {
                for( Pin pin : response.body()) {
                    MarkerOptions options = new MarkerOptions().position( new LatLng(pin.getLatitude(), pin.getLongitude()));
                    options.title(pin.getName());
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                    getMap().addMarker(options);
                }
            }

            @Override
            public void onFailure(Call<List<Pin>> call, Throwable t) {

            }
        });
    }
}

And below is my Main Activity that instantiates the navigation drawer and switches between the different tabs, including the "locations" tab. I included all the code because I'm not sure if there's something that needs to be changed in the Main Activity either. The code for switching between the fragments is found at the very bottom of the code in onDrawerSectionItemClickedEvent.

public class Home extends AppCompatActivity {

    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mActionBarDrawerToggle;
    private String mCurrentFragmentTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);

        mDrawerLayout = (DrawerLayout) findViewById( R.id.drawer_layout );

        mActionBarDrawerToggle = new ActionBarDrawerToggle(
                this,
                mDrawerLayout,
                R.string.drawer_opened,
                R.string.drawer_closed )

        {
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                if(getSupportActionBar() != null)
                    getSupportActionBar().setTitle(R.string.drawer_opened);

            }

            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                if(getSupportActionBar() != null)
                    getSupportActionBar().setTitle(R.string.drawer_closed);
            }
        };

        mDrawerLayout.addDrawerListener( mActionBarDrawerToggle );

        displayInitialFragment();
    }

    private void displayInitialFragment() {
        getSupportFragmentManager().beginTransaction().replace(R.id.container, HomeFragment.getInstance() ).commit();
        mCurrentFragmentTitle = getString(R.string.Home);
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState){
        super.onPostCreate(savedInstanceState);
        mActionBarDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mActionBarDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mActionBarDrawerToggle.onOptionsItemSelected( item ) )
            return true;

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getInstance().register( this );
    }

    @Override
    protected void onStop() {
        EventBus.getInstance().unregister( this );
        super.onStop();
    }

    @Subscribe
    public void onDrawerSectionItemClickedEvent(DrawerSectionItemClickedEvent event) {
        mDrawerLayout.closeDrawers();

        if(event == null || TextUtils.isEmpty( event.section ) || event.section.equalsIgnoreCase(mCurrentFragmentTitle))
        {
            return;
        }

        Toast.makeText( this, "Home: Section Clicked: " + event.section, Toast.LENGTH_SHORT).show();

        if(event.section.equalsIgnoreCase( "locations" )){
            getSupportFragmentManager().beginTransaction().replace(R.id.container, LocationFragment.getInstance()).commit();
        } else if (event.section.equalsIgnoreCase( "current members" ))
        {
            getSupportFragmentManager().beginTransaction().replace(R.id.container, MembersFragment.getInstance()).commit();
        } else if (event.section.equalsIgnoreCase( "home" ))
        {
            getSupportFragmentManager().beginTransaction().replace(R.id.container, HomeFragment.getInstance()).commit();
        } else {
            return;
        }

        mCurrentFragmentTitle = event.section;
    }
}

Solution

  • Step #1: Have LocationFragment implement OnMapReadyCallback.

    Step #2: Move all your current onViewCreated() logic into onMapReady() (required by OnMapReadyCallback)

    Step #3: In onViewCreated(), call getMapAsync(this)