I have looked at several posted solutions to similar questions, but none of them have worked. In the code below findFragmentById always returns null. I'm invoking MapLocationFragment from another fragment.
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapLocationFragment extends Fragment implements OnMapReadyCallback {
private String tag;
private OnFragmentInteractionListener mListener;
public MapLocationFragment() {} // Required
private FragmentActivity context;
private GoogleMap mMap;
#Override
public void onAttach(Context context) {
super.onAttach(context);
Log.d(tag, "onAttach");
this.context = (FragmentActivity)context;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tag = this.getClass().getSimpleName();
Log.d(tag, "onCreate");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(tag, "onCreateView");
View view = inflater.inflate(R.layout.fragment_map, container, false);
SupportMapFragment frag1 = (SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
return view;
}
#Override
public void onMapReady(GoogleMap googleMap) {
// ...
}
}
And the fragment layout (tried both fragment and FrameLayout)
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mapFragment"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.spireon.fai.fleetlocate.MapLocationFragment">
</fragment>
First, there is no android:name attribute for a FrameLayout. That is an attribute for <fragment>.
So, let's pretend that instead of <FrameLayout>, you have <fragment> instead, as you hint in your question.
In that case, your problem is that you are trying to find R.id.mapFragment before you inflate the layout that contains R.id.mapFragment. You need to inflate the layout before you can use findViewById() or findFragmentById() to access the contents of that layout.
use :
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
inside your xml File use:
<fragment
android:id="#+id/map"
android:name="dz.android.grcm.WorkaroundMapFragment"
android:layout_width="match_parent"
android:layout_height="300dp"
android:fragmentExitTransition="#layout/yourXmlFile" />
inside your manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="packageName"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="23" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<permission
android:name="packageName.permission.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="packageName.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your_APIKEY_"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity android:name="packageName.Time_Picker"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
for me it works with google_play_services_version : 7095000 and Android API 23
don't forget API_KEY, you have to générate it, refer to this link : console.developers.google.com
try it i hope it helps you .
After creating a new emulator, it started to work using the getChildFragmentManager() call. Thanks for the answers.
i have the same problem with SupportMapFragment i don't find it inside gms library the solution is to add this class WorkaroundMapFragment to your package:
package dz.android.grcm;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.google.android.gms.maps.MapFragment;;
public class WorkaroundMapFragment extends MapFragment {
private OnTouchListener mListener;
#SuppressWarnings("deprecation")
#Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle savedInstance) {
View layout = super.onCreateView(layoutInflater, viewGroup, savedInstance);
TouchableWrapper frameLayout = new TouchableWrapper(getActivity());
frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));
((ViewGroup) layout).addView(frameLayout,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return layout;
}
public void setListener(OnTouchListener listener) {
mListener = listener;
}
public interface OnTouchListener {
public abstract void onTouch();
}
public class TouchableWrapper extends FrameLayout {
public TouchableWrapper(Context context) {
super(context);
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mListener.onTouch();
break;
case MotionEvent.ACTION_UP:
mListener.onTouch();
break;
}
return super.dispatchTouchEvent(event);
}
}
}
then you call this class like this :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inscriptionmed);
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// *************Fix Scroll Map*******************************
if (map == null) {
map = ((WorkaroundMapFragment) getFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
map.getUiSettings().setZoomControlsEnabled(true);
map.setMyLocationEnabled(true);
mScrollView = (ScrollView) findViewById(R.id.partentScroll);
((WorkaroundMapFragment) getFragmentManager().findFragmentById(
R.id.map))
.setListener(new WorkaroundMapFragment.OnTouchListener() {
#Override
public void onTouch() {
mScrollView
.requestDisallowInterceptTouchEvent(true);
}
});
}
Related
I have a problem integrating google map in fragment in android. I know how to do it in activity but fragment reference on this site are very old and not working in 2018. I don't have any error.below is fragment file. Any help will be highly appreciated. I have added API key and proper manifest file.
package com.example.narmail.truck30mint.Api.Fragments;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.narmail.truck30mint.R;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class ViewTrucksFragment extends Fragment {
TextView pageTitle;
MapView mMapView;
private GoogleMap googleMap;
public ViewTrucksFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_view_trucks, container, false);
pageTitle = rootView.findViewById(R.id.view_trucks_title);
String load_id = getArguments().getString("load_id");
String load_from = getArguments().getString("load_from");
String load_to = getArguments().getString("load_to");
if (load_id != null && load_from != null && load_to != null) {
pageTitle.setText("Matching Trucks for "+load_from+" to "+load_to);
}
mMapView= rootView.findViewById(R.id.view_trucks_map);
mMapView.onCreate(savedInstanceState);
mMapView.onResume();
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mMapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
googleMap = mMap;
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
// For dropping a marker at a point on the Map
LatLng sydney = new LatLng(30.374219,76.782055);
googleMap.addMarker(new MarkerOptions().position(sydney).
title("Title").snippet("TitleName"));
// For zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition
(cameraPosition ));
}
});
/*----------------*/
return rootView;
}
}
and below is my layout file
<?xml version="1.0" encoding="utf-8"?>
<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"
android:background="#color/colorWhite"
tools:context=".Api.Fragments.ViewTrucksFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/view_trucks_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:padding="10dp"
android:textColor="#color/colorPrimary"
android:textSize="15sp"
android:text="#string/hello_blank_fragment" />
<com.google.android.gms.maps.MapView
android:id="#+id/view_trucks_map"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.google.android.gms.maps.MapView>
</LinearLayout>
</FrameLayout>
Please follow below step to finish your task. Just need to create 3 files
(1) Create XML layout for map inside your fragment layout fragment_map.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
(2) Create Fragment to load MAP MapFragment.Java
public class MapFragment extends Fragment implements OnMapReadyCallback {
private GoogleMap mMap;
public MapFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_map, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
if(getActivity()!=null) {
SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager()
.findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(this);
}
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Do your stuff here
}
}
(3) Create Activity to load MAP fragment MapsActivity.java
public class MapsActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.content,new MapFragment());
fragmentTransaction.commit();
}
}
For MAP key you need to follow same step you have done in your project. Hope this step will help you.
Inside Gradle please use below gradle
implementation 'com.google.android.gms:play-services-maps:15.0.1'
AndroidManifest.xml define below things.
<uses-permission android:name="android.permission.INTERNET"/>
Inside Application Tag.
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR MAP KEY" />
FATAL EXCEPTION: main
Process: org.example.easyparking, PID: 6371
java.lang.RuntimeException: Unable to start activity
ComponentInfo{org.example.easyparking/org.example.easyparking.MapActivity}:
android.view.InflateException: Binary XML file line #0: Binary XML
file line #0: Error inflating class fragment
This is my mapactivity
package org.example.easyparking;
import android.app.Dialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
public class MapActivity extends AppCompatActivity implements
OnMapReadyCallback {
GoogleMap mGoogleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
if(googleServicesAvailable()){
setContentView(R.layout.activity_map);
initMap();
}else{
//No Google Map Layout
}
}
private void initMap() {
MapFragment mapFragment = (MapFragment) getFragmentManager().
findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
}
public boolean googleServicesAvailable(){
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
int isAvailable = api.isGooglePlayServicesAvailable(this);
if(isAvailable == ConnectionResult.SUCCESS){
return true;
}else if (api.isUserResolvableError(isAvailable)){
Dialog dialog = api.getErrorDialog(this, isAvailable, 0);
dialog.show();
}else{
Toast.makeText(this, "Can't connect", Toast.LENGTH_LONG)
.show();
}
return false;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
}
}
This is menifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.example.easyparking">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<permission android:name="org.example.easyparking.permission.MAP_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="org.example.easyparking.permission.MAP_RECEIVE"/>
<uses-permission android:name="com.google.android.providers.gsf.permissions.READ_GSERVICES"/>
<uses-feature android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MapActivity" />
<activity
android:name=".SecondActivity">
</activity>
<meta-data android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyDGpV3ndPQ1Z4zf1nXi5AW1c7jGPL1La7Q"/>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
</application>
</manifest>
This is the first activity
package org.example.easyparking;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class FirstActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),
"Make sure that your location is turned on",
Toast.LENGTH_LONG).show();
Intent newacti = new Intent(FirstActivity.this, MapActivity.class);
startActivity(newacti);
}
});
Button button_parking_owner = (Button) this.findViewById(R.id.button2);
button_parking_owner.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newacti = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(newacti);
}
});
}
}
In your MapActivity you are checking if googleServicesAvailable() is available and if not you are not providing a default content to render
if(googleServicesAvailable()){
setContentView(R.layout.activity_map);
initMap();
}else{
//No Google Map Layout
}
try creating a basic layout to render that says something like No Google Map
i.e you should have something like
if(googleServicesAvailable()){
setContentView(R.layout.activity_map);
initMap();
}else{
//No Google Map Layout
setContentView(R.layout.no_activity_map);
}
then create a no_activity_map layout
I am working in a new Android project.
The first activity is using a slider menu and fragments. On the first fragment there is a list view (PrimaryFragmentDormir.java). After selecting one of the rows, a new activity is launched. This last activity uses three tabs, to show different information about the selected row object. The listview is loaded from remote JSON files.
The first tab shows details about the selected object, the second tab should show a map.
I have followed the official documentation to setup all the needed to include Google Maps on my app, at least I think so.
When the user selects the second tab, a blank screen is shown with the Google logo at the left bottom side.
Here is the Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.solinpromex.elpasojuarezexperience" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<uses-library android:name="com.google.android.maps"/>
<application
android:name=".app.AppController"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="..hidden here..." />
<activity
android:name=".Inicio"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name=".Detalle_Hotel"
android:label="#string/title_activity_detalle__hotel" >
</activity>
</application>
</manifest>
Here the main activity that hosts the tabs:
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
public class Detalle_Hotel extends AppCompatActivity {
// Declaring Your View and Variables
public String nombre_hotel_recibido, foto_hotel_recibido, descripcion_hotel_recibido,direccion_hotel_recibido,web_hotel,tel_hotel,tel_reservas,zona_hotel,facebook_hotel,twitter_hotel;
private int hotel_num_estrellas, id_hotel;
private double calificacion_hotel,latitud_hotel,longitud_hotel;
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Info","Mapa","Opinión"};
int Numboftabs =3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detalle__hotel);
nombre_hotel_recibido = getIntent().getStringExtra("nombre_hotel");
direccion_hotel_recibido = getIntent().getStringExtra("direccion_hotel");
descripcion_hotel_recibido = getIntent().getStringExtra("descripcion_hotel");
foto_hotel_recibido = getIntent().getStringExtra("foto_hotel");
hotel_num_estrellas = getIntent().getIntExtra("num_estrellas",0);
setTitle(nombre_hotel_recibido);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.rojomodesto);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
}
Here the code for the second tab:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class Tab2 extends Fragment {
private GoogleMap map;
static final LatLng HAMBURG = new LatLng(53.558, 9.927);
static final LatLng KIEL = new LatLng(53.551, 9.993);
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.tab_2, container, false);
return v;
}
#Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
map = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map))
.getMap();
if (map!=null){
Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = map.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.res)));
}
}
}
I have checked out the API key and it is OK.
Thank you for your support.
The problem is that when you call getActivity().getFragmentManager(), you're getting the Activity's Fragment Manager.
Since you're using a nested MapFragment inside of a Fragment, you need to use getChildFragmentManager(): For example:
GoogleMap mapFragment = ((MapFragment) getChildFragmentManager()
.findFragmentById(R.id.map)).getMap();
So, replace this:
map = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map))
.getMap();
With this:
map = ((MapFragment) getChildFragmentManager().findFragmentById(R.id.map))
.getMap();
However, while that would work, you would be better off having your Fragment extend MapFragment or SupportMapFragment, that way you wouldn't need to have nested Fragments, and you would avoid the potential of running into this problem.
Solution using TabLayout from the support library:
As ActionBar Tabs are deprecated, this is now the best way to implement tabs with a ViewPager. Notice this is done without use of a nested SupportMapFragment, and instead has the map Fragment extent SupportMapFragment:
MainActivity imports:
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v4.app.FragmentManager;
import android.view.View;
import android.widget.TextView;
MainActivity class:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
PagerAdapter pagerAdapter =
new PagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class PagerAdapter extends FragmentPagerAdapter {
String tabTitles[] = new String[] { "Tab One", "Tab Two", "Tab Three", };
Context context;
public PagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new BlankFragment();
case 1:
return new BlankFragment();
case 2:
return new MapFragment();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
public View getTabView(int position) {
View tab = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) tab.findViewById(R.id.custom_text);
tv.setText(tabTitles[position]);
return tab;
}
}
}
The MapFragment, notice that it directly extends SupportMapFragment instead of having a nested SupportMapFragment inside it:
import android.util.Log;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapFragment extends SupportMapFragment implements
OnMapReadyCallback {
private final LatLng HAMBURG = new LatLng(53.558, 9.927);
private final LatLng KIEL = new LatLng(53.551, 9.993);
private static final String ARG_SECTION_NUMBER = "section_number";
private GoogleMap mMap;
private Marker marker;
public MapFragment() {
}
#Override
public void onResume() {
super.onResume();
Log.d("MyMap", "onResume");
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
Log.d("MyMap", "setUpMapIfNeeded");
getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
Log.d("MyMap", "onMapReady");
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
Marker hamburg = mMap.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = mMap.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.mipmap.ic_launcher)));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
}
layout xml for the Activity:
<RelativeLayout
android:id="#+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
app:tabMode="fixed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
app:tabTextColor="#d3d3d3"
app:tabSelectedTextColor="#ffffff"
app:tabIndicatorColor="#ff00ff"
android:minHeight="?attr/actionBarSize"
/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
</RelativeLayout>
custom_tab.xml, which is the layout for each tab:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/custom_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:textSize="16dip"
android:textColor="#ffffff"
android:singleLine="true"
/>
</LinearLayout>
Gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
compile 'com.google.android.gms:play-services:7.0.0'
}
Result:
I'm trying to put a google maps fragment in another fragment, and that fragment is part of a viewpager. The initial part of it works, the map fragment gets put on my phone's screen.
The activity uses a viewpager that has 3 fragments, the fragment with the map fragment in it is the first one you see, but when i swipe to the last fragment and then go back to the middle fragment, the app crashes and i get an inflateException in the OnCreateView method of my first fragment (the one with the map).
I have no idea how to fix this, and nothing i tried makes it work. Any help with this would be greatly appreciated.
The fragment with the mapfragment in it.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tV_welkomtekst"
android:textSize="25dp"
android:layout_gravity="center"/>
<TextView
android:text="#string/sportdropdown_tekst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"/>
<Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/spinSporten"></Spinner>
<fragment
android:layout_width="match_parent"
android:layout_height="300sp"
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/tekst_startWorkout"/>
The activity that holds the fragments.
package desomer_michael_2app.desomer_michael_eindopdracht_app;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class SportActivity extends FragmentActivity implements SportStatsFragment.OnSportStatsFragmentInteractionListener, SportStartFragment.OnSportStartFragmentInteractionListener, SportBadgesFragment.OnSportBadgesFragmentInteractionListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sport);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
/*
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new SportStartFragment())
.commit();
}
*/
}
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
//getSupportFragmentManager().putFragment(outState, "sportStartFragment", );
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_sport, menu);
return true;
}
public void uitloggen(){
//Intent i = new Intent("android.intent.action.MAIN");
//startActivity(i);
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(id){
case R.id.log_out:
uitloggen();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
The viewpager
package desomer_michael_2app.desomer_michael_eindopdracht_app;
import android.support.v4.app.FragmentManager;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
/**
* Created by Michaël Desomer on 25/04/2015.
*/
public class ViewPagerAdapter extends FragmentPagerAdapter{
final int PAGE_COUNT = 3;
private String tabtitles[] = new String[]{"Start","Stats","Badges"};
Context context;
public ViewPagerAdapter(FragmentManager fm){
super(fm);
}
#Override
public Fragment getItem(int i) {
switch(i){
case 0:
SportStartFragment sportStartFragment = new SportStartFragment();
return sportStartFragment;
case 1:
SportStatsFragment sportStatsFragment = new SportStatsFragment();
return sportStatsFragment;
case 2:
SportBadgesFragment sportBadgesFragment = new SportBadgesFragment();
return sportBadgesFragment;
default:
return null;
}
//return null;
}
#Override
public CharSequence getPageTitle(int position){
return tabtitles[position];
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
My android manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".LoginRegistreerActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SportActivity"
android:label="#string/title_activity_sport" >
<intent-filter>
<action android:name="create_sportactivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value=""/>
</application>
The error message
05-02 15:57:01.360 19662-19662/desomer_michael_2app.desomer_michael_eindopdracht_app E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.view.InflateException: Binary XML file line #30: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at desomer_michael_2app.desomer_michael_eindopdracht_app.SportStartFragment.onCreateView(SportStartFragment.java:57)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1302)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:729)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:486)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
at android.support.v4.view.ViewPager$3.run(ViewPager.java:249)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
at android.view.Choreographer.doCallbacks(Choreographer.java:591)
at android.view.Choreographer.doFrame(Choreographer.java:560)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #30: Duplicate id 0x7f09006d, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
at desomer_michael_2app.desomer_michael_eindopdracht_app.SportStartFragment.onCreateView(SportStartFragment.java:57)
(there were quite bit more, but i couldn't get them all in the code format)
The SportStatsFragment
package desomer_michael_2app.desomer_michael_eindopdracht_app;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link SportStatsFragment.OnSportStatsFragmentInteractionListener} interface
* to handle interaction events.
*/
public class SportStatsFragment extends Fragment {
private OnSportStatsFragmentInteractionListener mListener;
public SportStatsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sport_stats, container, false);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnSportStatsFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnSportStatsFragmentInteractionListener {
// TODO: Update argument type and name
}
}
The problem is that you are using the same map again and again (Duplicate id 0x7f09006d) without destroying.
The case is destroy fragment
#Override
public void onDestroyView()
{
super.onDestroyView();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft= getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
package com.panorma.views.fragments.contact;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLndg;
import com.google.android.gms.maps.model.MarkerOptions;
import com.panorma.R;
/**
* Created by aateek on 3/10/2016.
*/
// In this case, the fragment displays simple text based on the page
public class MapViewPagerFragment extends Fragment {
private static View rootView;
private final double LATITUDE = *********;
private final double LONGITUDE = ********;
GoogleMap googleMap;
private SupportMapFragment mapFrag;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null)
parent.removeView(rootView);
}
try {
rootView = inflater.inflate(R.layout.fragment_contacts, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
Log.d("InflateException", "onCreateView: ");
}
initMap();
return rootView;
}
private void initMap() {
LatLng location = new LatLng(LATITUDE, LONGITUDE);
FragmentManager fm = getChildFragmentManager();
mapFrag = (SupportMapFragment) fm.findFragmentById(
R.id.map);
if (mapFrag != null) {
googleMap = mapFrag.getMap();
}
if (googleMap != null) {
googleMap.getUiSettings().setMyLocationButtonEnabled(false);
googleMap.addMarker(new MarkerOptions().position(location));
MapsInitializer.initialize(this.getActivity());
// Updates the location and zoom of the MapView
CameraUpdate initalUpdate = CameraUpdateFactory.newLatLngZoom(
location, 17.0f);
googleMap.animateCamera(initalUpdate);
}
}
}
android.view.InflateException: Binary XML file line #6: Error inflating class fragment
I am trying to implement Google Map apiv2 in fragments following various tutorials , I ran into error inflating class fragment , then I came across various similar problems at stackoverflow , tried almost everything but the problem persist. I am new to android , any type of hints are welcome, i want to learn android development quick but I am stuck . thanks in advance.
edit: application closes unexpectedly when I go from fragment 3 to fragment 2 and fragment 1 is loaded in the background . Any ideas to solve such issues?
My android manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hspot2"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="18" />
<permission
android:name="com.example.hspot2.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Required OpenGL ES 2.0. for Maps V2 -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.hspot2.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyDOeSK3RC57lSdERhR0tnadCSA"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"
/>
</application>
</manifest>
My main activity where I am implementing swipe tabs using fragments :
import java.util.Locale;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
if(i==0){
fragment = new FragmentA();
}
if(i==1){
fragment = new FragmentB();
}
if(i==2){
fragment = new FragmentC();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
}
My fragment_a.xml where I am implementing map layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#FFCC00" >
<fragment android:id="#+id/map1"
android:layout_width="match_parent"
android:layout_height="match_parent"
class = "com.google.android.gms.maps.SupportMapFragment"
/>
</RelativeLayout>
fragmentA.java file :
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class FragmentA extends Fragment{
static final LatLng HAMBURG = new LatLng(53.558, 9.927);
GoogleMap map;
MapView mapView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
map = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map1)).getMap();
return v;
}
}
Try following solution, which works like a charm.
1) Go to XML file and write as below :
<fragment
android:id="#+id/citymap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="com.google.android.gms.maps.SupportMapFragment"/>
2) Now go to your Activity and make changes as below :
=> Go to appropriate method and copy below code,
FragmentManager myFragmentManager = getChildFragmentManager();
SupportMapFragment mySupportMapFragment
=(SupportMapFragment)myFragmentManager.findFragmentById(R.id.citymap);
GoogleMap googlemap=mySupportMapFragment.getMap();