{"id":336,"date":"2014-09-09T20:45:13","date_gmt":"2014-09-09T18:45:13","guid":{"rendered":"http:\/\/michalu.eu\/wordpress\/?p=336"},"modified":"2015-04-27T10:15:20","modified_gmt":"2015-04-27T08:15:20","slug":"android-mapfragment-nested-in-parent-fragment","status":"publish","type":"post","link":"https:\/\/michalu.eu\/wordpress\/android-mapfragment-nested-in-parent-fragment\/","title":{"rendered":"Android: MapFragment nested in parent fragment"},"content":{"rendered":"<p style=\"text-align: justify;\">Would you like to show map in your smart Android app? It is <strong>very easy,<\/strong> but after successfully passed some steps. In this tutorial I would like to make these steps with you to make the process faster and in a specific case &#8211; we will show\u00a0our <strong>map in nested fragment<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Before funny work with the Android code we need to go through basic checkpoint list:<\/p>\n<ol style=\"text-align: justify;\">\n<li>Check if you have installed a <strong>Google Play Services<\/strong> in your <strong>Android SDK Manager<\/strong>. If no of course please install it! Second part of this point is to import the <strong>google-play-services-lib<\/strong> project into your <strong>workspace<\/strong>.<\/li>\n<li>Find your <strong>debug.keystore<\/strong> (or other) to list\u00a0some details about it (like <strong>SHA-1<\/strong> hash which is extremly important to accomplish next step.<\/li>\n<li>Create <strong>Google Maps API Key<\/strong> basing on SHA-1 from 2nd step and your <strong>application package name<\/strong>.<\/li>\n<\/ol>\n<p><!--more--><\/p>\n<p style=\"text-align: justify;\">Don&#8217;t worry! It is very easy and quick job. I created a short clip which explains everything (I think so, if not please follow <a href=\"https:\/\/developers.google.com\/maps\/documentation\/android\/start#overview\" target=\"_blank\">this <\/a>guide)<\/p>\n<p><iframe loading=\"lazy\"  id=\"_ytid_20250\"  width=\"480\" height=\"270\"  data-origwidth=\"480\" data-origheight=\"270\" src=\"https:\/\/www.youtube.com\/embed\/163uIkkjwls?enablejsapi=1&#038;autoplay=0&#038;cc_load_policy=0&#038;cc_lang_pref=&#038;iv_load_policy=1&#038;loop=0&#038;rel=1&#038;fs=1&#038;playsinline=0&#038;autohide=2&#038;theme=dark&#038;color=red&#038;controls=1&#038;disablekb=0&#038;\" class=\"__youtube_prefs__  epyt-is-override  no-lazyload\" title=\"YouTube player\"  allow=\"fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\"><\/iframe><\/p>\n<p style=\"text-align: justify;\">4. Next step\u00a0is to\u00a0download\u00a0tutorial project from <a href=\"https:\/\/github.com\/fockeRR\/michalueu-examples\/tree\/master\/NestedMapFragmentTutorial\" target=\"_blank\">repository <\/a>(or from <a href=\"http:\/\/michalu.eu\/wordpress\/wp-content\/uploads\/2014\/09\/NestedMapFragmentTutorial.zip\" target=\"_blank\">here<\/a>) and import it to your workspace. <strong>Remeber to add previously imported google-play-services-lib project as library! And don&#8217;t forget about downloading platform with Google API image in your SDK Manager!<\/strong><\/p>\n<p style=\"text-align: justify;\">The project contains a lot of files, but the most important are:<\/p>\n<ul style=\"text-align: justify;\">\n<li>AndroidManifest.xml<\/li>\n<li>ActivityWithMap.java<\/li>\n<li>AddressDetailsFragment.java<\/li>\n<li>MyMapFragment.java<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">First of all &#8211; <strong>manifest<\/strong>. Surely you found\u00a0new xml tags there. First one is declaration of <strong>uses-feature<\/strong> &#8211; we specify version of OpenGL ES which is required to run the app. Next there are some r<strong>equired and recommended permissions.<\/strong> Last but not least metadata tags where one of them contains previously created Maps API Key &#8211; this really important tag.<\/p>\n<pre class=\"brush: xml; highlight: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,25]; title: ; notranslate\" title=\"\">\r\n&lt;uses-feature\r\nandroid:glEsVersion=&quot;0x00020000&quot;\r\nandroid:required=&quot;true&quot; \/&gt;\r\n\r\n&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; \/&gt;\r\n&lt;uses-permission android:name=&quot;android.permission.ACCESS_NETWORK_STATE&quot; \/&gt;\r\n&lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; \/&gt;\r\n&lt;!--\r\nThe following two permissions are not required to use\r\nGoogle Maps Android API v2, but are recommended.\r\n--&gt;\r\n&lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot; \/&gt;\r\n&lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot; \/&gt;\r\n\r\n&lt;application\r\nandroid:allowBackup=&quot;true&quot;\r\nandroid:icon=&quot;@drawable\/ic_launcher&quot;\r\nandroid:label=&quot;@string\/app_name&quot;\r\nandroid:theme=&quot;@style\/AppTheme&quot; &gt;\r\n&lt;meta-data\r\nandroid:name=&quot;com.google.android.gms.version&quot;\r\nandroid:value=&quot;@integer\/google_play_services_version&quot; \/&gt;\r\n&lt;meta-data\r\nandroid:name=&quot;com.google.android.maps.v2.API_KEY&quot;\r\nandroid:value=&quot;AIzaSyD8wfjeLpfhgLRs9I9zweaSJDNRpQsEGrQ&quot; \/&gt;\r\n\r\n&lt;activity\r\nandroid:name=&quot;.ActivityWithMap&quot;\r\nandroid:label=&quot;@string\/app_name&quot;\r\nandroid:theme=&quot;@android:style\/Theme.Black.NoTitleBar&quot; &gt;\r\n&lt;intent-filter&gt;\r\n&lt;action android:name=&quot;android.intent.action.MAIN&quot; \/&gt;\r\n\r\n&lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; \/&gt;\r\n&lt;\/intent-filter&gt;\r\n&lt;\/activity&gt;\r\n&lt;\/application&gt;\r\n<\/pre>\n<p style=\"text-align: justify;\"><strong>ActivityWithMap.java<\/strong> &#8211; nothing special here. Creating test data and adding fragment with address details &#8211; that&#8217;s all. Address class is a simple model to store data like street, town and coordinates (LatLng object)<\/p>\n<pre class=\"brush: java; highlight: [23]; title: ; notranslate\" title=\"\">\r\npackage eu.michalu.nestedmapfragment;\r\n\r\nimport com.google.android.gms.maps.model.LatLng;\r\n\r\nimport android.os.Bundle;\r\nimport android.support.v4.app.FragmentActivity;\r\nimport android.support.v4.app.FragmentManager;\r\nimport android.support.v4.app.FragmentTransaction;\r\nimport eu.michalu.nestedmapfragment.model.Address;\r\n\r\npublic class ActivityWithMap extends FragmentActivity {\r\n\r\nAddress address = null;\r\n\r\n@Override\r\nprotected void onCreate(Bundle savedInstanceState) {\r\n\/\/ TODO Auto-generated method stub\r\nsuper.onCreate(savedInstanceState);\r\nsetContentView(R.layout.activity);\r\n\r\naddress = new Address(&quot;Marsza\u0142kowska Street&quot;, &quot;Warsaw&quot;, new LatLng(52.228083, 21.012967));\r\n\r\nFragmentManager fm = getSupportFragmentManager();\r\nAddressDetailsFragment addressFragment = (AddressDetailsFragment) fm.findFragmentByTag(&quot;address_fragment&quot;);\r\n\r\nif (addressFragment == null) {\r\nFragmentTransaction ft = fm.beginTransaction();\r\nft.replace(R.id.fragment_container_for_map, AddressDetailsFragment.newInstance(address), &quot;address_fragment&quot;);\r\nft.commit();\r\nfm.executePendingTransactions();\r\n}\r\n\r\n}\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">Hint: Highlighted line tells\u00a0you that here we use activity&#8217;s\u00a0fragment manager.<\/p>\n<p style=\"text-align: justify;\"><strong>AddressDetailsFragment.java<\/strong> &#8211; In the fragment we will check if\u00a0<strong>Android have access to Google Play services<\/strong> (and if everything seems to be ok) and load fragment with the map in proper container declared in XML file with layout. Please note that here we used <strong>ChildFragmentManager<\/strong>!<\/p>\n<pre class=\"brush: java; highlight: [41,42,43,44,45,46,47,48,49,50,51,52,52]; title: ; notranslate\" title=\"\">\r\npackage eu.michalu.nestedmapfragment;\r\n\r\nimport android.os.Bundle;\r\nimport android.support.v4.app.Fragment;\r\nimport android.support.v4.app.FragmentManager;\r\nimport android.support.v4.app.FragmentTransaction;\r\nimport android.view.LayoutInflater;\r\nimport android.view.View;\r\nimport android.view.ViewGroup;\r\nimport android.widget.TextView;\r\n\r\nimport com.google.android.gms.common.ConnectionResult;\r\nimport com.google.android.gms.common.GooglePlayServicesUtil;\r\n\r\nimport eu.michalu.nestedmapfragment.model.Address;\r\n\r\npublic class AddressDetailsFragment extends Fragment {\r\nprivate TextView mStreet;\r\nprivate TextView mTown;\r\n\r\npublic static AddressDetailsFragment newInstance(Address venue) {\r\nAddressDetailsFragment fragment = new AddressDetailsFragment();\r\nfragment.setRetainInstance(true);\r\nBundle b = new Bundle();\r\nb.putSerializable(&quot;address&quot;, venue);\r\nfragment.setArguments(b);\r\nreturn fragment;\r\n}\r\n\r\n@Override\r\npublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r\n\/\/ TODO Auto-generated method stub\r\nView v = inflater.inflate(R.layout.details_view, container, false);\r\n\r\nBundle args = getArguments();\r\nAddress address = null;\r\nif (args.containsKey(&quot;address&quot;)) {\r\naddress = (Address) args.getSerializable(&quot;address&quot;);\r\n}\r\n\r\nint status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());\r\n\/\/ Showing status\r\nif (status == ConnectionResult.SUCCESS) {\r\n{\r\nFragmentManager fm = getChildFragmentManager();\r\nMyMapFragment mMapFragment = MyMapFragment.newInstance(address.getCoordinates());\r\nFragmentTransaction fragmentTransaction = fm.beginTransaction();\r\nfragmentTransaction.add(R.id.my_map_fragment, mMapFragment);\r\nfragmentTransaction.commit();\r\nfm.executePendingTransactions();\r\n}\r\n}\r\nmStreet = (TextView) v.findViewById(R.id.address_details_street);\r\nmTown = (TextView) v.findViewById(R.id.address_details_town);\r\nmStreet.setText(address.getStreet());\r\nmTown.setText(address.getTown());\r\n\r\nreturn v;\r\n}\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\"><strong>MyMapFragment.java<\/strong> &#8211; of course I don&#8217;t forget about our hero-fragment with map. This fragment extends <strong>SupportMapFragment<\/strong> (Google API) and in <strong>onCreateView<\/strong> initializes the map.<\/p>\n<pre class=\"brush: java; highlight: [29,33,34,35,36,37,38,39]; title: ; notranslate\" title=\"\">\r\npackage eu.michalu.nestedmapfragment;\r\n\r\nimport android.os.Bundle;\r\nimport android.view.LayoutInflater;\r\nimport android.view.View;\r\nimport android.view.ViewGroup;\r\n\r\nimport com.google.android.gms.maps.CameraUpdateFactory;\r\nimport com.google.android.gms.maps.SupportMapFragment;\r\nimport com.google.android.gms.maps.model.LatLng;\r\nimport com.google.android.gms.maps.model.MarkerOptions;\r\n\r\npublic class MyMapFragment extends SupportMapFragment {\r\nprivate LatLng mPosition;\r\n\r\npublic MyMapFragment() {\r\nsuper();\r\n}\r\n\r\npublic static MyMapFragment newInstance(LatLng position) {\r\nMyMapFragment frag = new MyMapFragment();\r\nfrag.mPosition = position;\r\nreturn frag;\r\n}\r\n\r\n@Override\r\npublic View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {\r\nView v = super.onCreateView(arg0, arg1, arg2);\r\ninitMap();\r\nreturn v;\r\n}\r\n\r\nprivate void initMap() {\r\ngetMap().moveCamera(CameraUpdateFactory.newLatLngZoom(mPosition, 15));\r\ngetMap().addMarker(new MarkerOptions().position(mPosition));\r\ngetMap().getUiSettings().setAllGesturesEnabled(true);\r\ngetMap().getUiSettings().setCompassEnabled(true);\r\n}\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\"><strong>initMap()<\/strong> method moves camera to (passed by argument) position and set\u00a0zoom to 15. In next lines the <strong>marker, gestures and compas\u00a0are enabled<\/strong>.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/michalu.eu\/wordpress\/wp-content\/uploads\/2014\/09\/Screenshot_2014-09-09-20-36-36.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-359 size-medium\" src=\"http:\/\/michalu.eu\/wordpress\/wp-content\/uploads\/2014\/09\/Screenshot_2014-09-09-20-36-36-168x300.png\" alt=\"Working app\" width=\"168\" height=\"300\" srcset=\"https:\/\/michalu.eu\/wordpress\/wp-content\/uploads\/2014\/09\/Screenshot_2014-09-09-20-36-36-168x300.png 168w, https:\/\/michalu.eu\/wordpress\/wp-content\/uploads\/2014\/09\/Screenshot_2014-09-09-20-36-36-576x1024.png 576w, https:\/\/michalu.eu\/wordpress\/wp-content\/uploads\/2014\/09\/Screenshot_2014-09-09-20-36-36.png 720w\" sizes=\"auto, (max-width: 168px) 100vw, 168px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Main project is available on my <strong>github<\/strong> <a href=\"https:\/\/github.com\/fockeRR\/michalueu-examples\" target=\"_blank\">profile<\/a>\u00a0but please remember to add one dependency from your local filesystem: <span style=\"text-decoration: underline;\">google-play-services-lib project\u00a0<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>Working APK<\/strong> file is available <a title=\"Working apk file\" href=\"https:\/\/drive.google.com\/file\/d\/0B1d8wa4Eh9QlSlk2dS0xNTFaTnM\/edit?usp=sharing\" target=\"_blank\">here<\/a>.<\/p>\n<p style=\"text-align: justify;\">Leave your comment below, share this article and thanks for reading!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Would you like to show map in your smart Android app? It is very easy, but after successfully passed some [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[8,22,91,12],"tags":[],"class_list":["post-336","post","type-post","status-publish","format-standard","hentry","category-android","category-developers","category-eclipse","category-google-play"],"_links":{"self":[{"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/posts\/336","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/comments?post=336"}],"version-history":[{"count":26,"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/posts\/336\/revisions"}],"predecessor-version":[{"id":364,"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/posts\/336\/revisions\/364"}],"wp:attachment":[{"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/media?parent=336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/categories?post=336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michalu.eu\/wordpress\/wp-json\/wp\/v2\/tags?post=336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}