Error trying to load google maps in a fragment? Android Studio:

0

Good morning, I'm doing the exercise of placing a map to my app, I already did an exercise that worked correctly for me using an activity, but now I'm doing it with Fragment in a navigation drawer and it shows me error in the line:

Shown: Inconvertible types; cannont cast 'android.support.v4.app.Fragment' to 'com.google.android.gms.maps.MapFragment'

MapFragment fragment =(MapFragment)getChildFragmentManager().findFragmentById(R.id.map);

If someone can help me, thank you very much.

Next the code:

public class MapActivity extends Fragment implements OnMapReadyCallback {

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment


    return inflater.inflate(R.layout.map_layout, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    MapFragment fragment = (MapFragment)getChildFragmentManager().findFragmentById(R.id.map);
    fragment.getMapAsync(this);

}

@Override
public void onMapReady(GoogleMap googleMap) {

    LatLng bogota = new LatLng(4.653421, -74.145150);
    googleMap.addMarker(new MarkerOptions().position(bogota)
            .title("Uniagustiniana"));
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(bogota, 16.1f));

    }
}

The file map_layout.xml :

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tecnologias.uniagustinianaapp.MapActivity">

<fragment android:id="@+id/map"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.MapFragment"></fragment>

As it is a set of fragments that are replaced by transactions in MainActivity, when I change // import android.support.v4.app.Fragment; a // import android.app.Fragment; I get error in the MainActivity this because in all the fragments I import support.v4, the following is the MainActivity:

public class MainActivity extends AppCompatActivity
    implements  NavigationView.OnNavigationItemSelectedListener, Portal.OnFragmentInteractionListener, Biblioteca.OnFragmentInteractionListener, Evu.OnFragmentInteractionListener,
                Directorio.OnFragmentInteractionListener, Siga.OnFragmentInteractionListener, Moodle.OnFragmentInteractionListener, Facebook.OnFragmentInteractionListener,
                Twitter.OnFragmentInteractionLiastener, LinkedIn.OnFragmentInteractionListener, GooglePlus.OnFragmentInteractionListener, Flickr.OnFragmentInteractionListener,
                Tour.OnFragmentInteractionListener, Instagram.OnFragmentInteractionListener, Youtube.OnFragmentInteractionListener, Noticias.OnFragmentInteractionListener,
                Home.OnFragmentInteractionListener, Whatsapp.OnFragmentInteractionListener, MapActivity.OnFragmentInteractionListener {
//Bottom
private BottomNavigationView bottomNavigationView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setItemIconTintList(null);//Los iconos del menu lateral toman su color original

    //BOTTON NAVIGATION VIEW

    final Fragment home = new Home();
    final Fragment noticias = new Noticias();
    final Fragment calendario = new Calendario();
    final Fragment ubicacion = new MapActivity();
    final Fragment pqrs = new PQRS();
    final Fragment preinscrip = new PreInscripcion();

    //FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    //fragmentTransaction.replace(R.id.content_main, home).commit();

    //FragmentManager fragmentManager = getSupportFragmentManager();
    //fragmentManager.beginTransaction().replace(R.id.content_main, new Home()).commit();


    if(savedInstanceState == null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_main, new Home()).commit();
    }

    bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
    bottomNavigationView.setItemIconTintList(null);//Los iconos del menu Bottom toman su color original
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {

            FragmentManager fragmentManager = getSupportFragmentManager();

            if (item.getItemId() == R.id.noticias) {
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.content_main, noticias).commit();
            } else if (item.getItemId() == R.id.rutas) {
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.content_main, ubicacion).commit();
            } else if (item.getItemId() == R.id.cal_aca) {
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.content_main, calendario).commit();
            } else if (item.getItemId() == R.id.pqrs) {
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.content_main, pqrs).commit();
            } else if (item.getItemId() == R.id.preinscripcion) {
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.content_main, preinscrip).commit();
            }
            return true;
        }
    });
}
    
asked by Ivan Alfredo 24.08.2017 в 16:26
source

2 answers

1

The getChildFragmentManager() method was introduced from API 17. If your minimum API is 17 ( minSdkVersion 17 ) then there should be no problem. The libraries of Fragment NOT of Support Fragment must be imported in all the fragments. Try this code in onViewCreated of your MapActivity fragment:

import android.app.Fragment;  //este en todos los Fragments que tengas
import com.google.android.gms.maps.MapFragment;
    ...  onViewCreated ...
MapFragment fragment = (MapFragment)getChildFragmentManager().findFragmentById(R.id.map);
fragment.getMapAsync(this);

In the xml:

 class="com.google.android.gms.maps.MapFragment"/>

In the Main Activity you must also import the Fragment library:

 import android.app.FragmentTransaction;

And the transactions of the Fragments would look like this:

MapActivity fragment = new MapActivity();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frame, fragment, "mapactivity");
ft.commit();

If your minSdkVersion is -16 then you must use the Support Fragment libraries. Map Activity must be of type Support Fragment , other fragments not necessarily:

import android.support.v4.app.Fragment; 
import.com.google.android.gms.maps.SupportMapFragment; 
....
 SupportMapFragment fragment = (SupportMapFragment)
 getChildFragmentManager().findFragmentById(R.id.map);
 fragment.getMapAsync(this);

In the xml:

 class="com.google.android.gms.maps.SupportMapFragment"/>

In the Main Activity import the Support Fragment library:

 import android.support.v4.app.FragmentTransaction;

And the transactions of the Fragments would look like this:

MapActivity fragment = new MapActivity(); 
FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.frame,
fragment, "mapactivity"); ft.commit();

In case of having other fragments that in your java code have imported the Fragment library (NOT the Support Fragment), in the transactions change to this line:

 android.app.FragmentTransaction ft =getFragmentManager().beginTransaction();

The map_layout.xml should look like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<fragment
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.tecnologias.uniagustinianaapp.MapActivity"
    class="com.google.android.gms.maps.MapFragment"/>

    
answered by 25.08.2017 / 23:31
source
1

in your xml do not use this tag to show the map:

<fragment android:id="@+id/map"
android:layout_width="wrap_content"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"></fragment>

I recommend you use something like this:

<com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

And to your fragment you assign it with the findById to a variable of type MapView.

You can also in the xml put the ..MapView tag inside a FrameLayout in order besides not doing it in the activity's xml. You have to make a FrameLayout in the xml like this and already:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/contentFrame"
  tools:context="com.tecnologias.uniagustinianaapp.MapActivity">

Then in your MainActivity you inflate the fragment with the findById (contentFrame) that would be the fragment and already in the xml of the fragment you make a FrameLayout with what I put at the beginning and remember 2 important things:

1) Use this method to start the getMapAsync (this) map and for the "this" to work the chart must implement this OnMapReadyCallback interface.

I hope it serves you.

    
answered by 24.08.2017 в 16:56