Google Map In Fragment Kotlin Example MapView Android

best android development course on udemy, google map in fragment kotlin, show current location on map kotlin, Kotlin Volley JSON Parsing, Kotlin Detect Shake, kotlin google map

Welcome to Google Map In Fragment Kotlin Example MapView Android.

In this kotlin google map example, you will learn how to integrate google mapview inside the fragment.

Generally, to integrate google map in fragment is little bit complex than to integrate it in the activity.

But this tutorial will help you to load google map in fragment with easy and simple kotlin source code.

First of all, watch the following output video to have some idea of the feature of this example.

Getting Google API Key

To load the google map in fragment using kotlin, we need to create one app in the developer console of google.

And after making an app, we need to generate Google API key.

Here is the specific tutorial how to generate API for google map in kotlin android.

So go through the above tutorial first and then come back with the Google API.

Android Studio Work

Now make a new brand new project in the android studio.

While making new project, make sure you have selected “Empty activity” as the default one.

If you select “Map Activity” then compiler write some lines of code which is difficult to understand.

Also, you should select “Kotlin” as the source language for the project.

Gradle Changes

Go to your build.gradle(Module:app) file, and add the following line

 implementation 'com.google.android.gms:play-services:12.0.1'

This line will integrate google play services in our project.

It will allow us to use various services like map, push notification, google earth etc. in our android app.

Manifest Toppings

Open your AndroidManifest.xml file. Add the following lines inside <application> tags.

<meta-data
                android:name="com.google.android.geo.API_KEY"
                android:value="AIza............FQ"/>

Look at the attribute “android:value” . You can see that I have written my Google API key in it.

Simply replace my Google API key with yours.

Now, outside of <application> tags, add the following coding lines

 <uses-feature
            android:glEsVersion="0x00020000"
            android:required="true"/>

So the final source code for AndroidManifest.xml file is as the below

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.mapfragmentkotlin">

    <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">

        <meta-data
                android:name="com.google.android.geo.API_KEY"
                android:value="AIz........FQ"/>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

    <uses-feature
            android:glEsVersion="0x00020000"
            android:required="true"/>

</manifest>

Spider man Image

This example need one image to show as the marker on the google map.

So, click the following link to download the image of the spider man.

https://demonuts.com/wp-content/uploads/2018/09/spidy.zip

After downloading the image, save it inside app->res->drawable directory.

Two Fragments

Make a new fragment with the name as OneFragment.

Inside your fragment_one.xml file, add the following lines of code

<?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"
             tools:context=".OneFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorAccent"
            android:textColor="#fff"
            android:gravity="center"
            android:textSize="35dp"
            android:text="One Fragment" />

</FrameLayout>

There is one text view in the above file.

Background of the text view is of pink color and it has text value as “One Fragment”

Now in your OneFragment.kt file, write down the below code lines

import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class OneFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_one, container, false)
    }

}// Required empty public constructor

Now create another fragment and set it’s name as the MapFragment.

In your fragment_map.xml file, add the below source snippet

<?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"
             tools:context=".MapFragment">

    <fragment
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:id="@+id/frg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

</FrameLayout>

Below is the source code snippet for the MapFragment.kt file.

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
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.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.CameraPosition
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions

class MapFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val rootView = inflater.inflate(R.layout.fragment_map, container, false)

        val mapFragment =
            childFragmentManager.findFragmentById(R.id.frg) as SupportMapFragment?  //use SuppoprtMapFragment for using in fragment instead of activity  MapFragment = activity   SupportMapFragment = fragment
        mapFragment!!.getMapAsync { mMap ->
            mMap.mapType = GoogleMap.MAP_TYPE_NORMAL

            mMap.clear() //clear old markers

            val googlePlex = CameraPosition.builder()
                .target(LatLng(37.4219999, -122.0862462))
                .zoom(10f)
                .bearing(0f)
                .tilt(45f)
                .build()

            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(googlePlex), 10000, null)

            mMap.addMarker(
                MarkerOptions()
                    .position(LatLng(37.4219999, -122.0862462))
                    .title("Spider Man")
                    .icon(bitmapDescriptorFromVector(activity, R.drawable.spider))
            )

            mMap.addMarker(
                MarkerOptions()
                    .position(LatLng(37.4629101, -122.2449094))
                    .title("Iron Man")
                    .snippet("His Talent : Plenty of money")
            )

            mMap.addMarker(
                MarkerOptions()
                    .position(LatLng(37.3092293, -122.1136845))
                    .title("Captain America")
            )
        }

        return rootView
    }

    private fun bitmapDescriptorFromVector(context: Context?, vectorResId: Int): BitmapDescriptor {
        val vectorDrawable = ContextCompat.getDrawable(context!!, vectorResId)
        vectorDrawable!!.setBounds(0, 0, vectorDrawable.intrinsicWidth, vectorDrawable.intrinsicHeight)
        val bitmap =
            Bitmap.createBitmap(vectorDrawable.intrinsicWidth, vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        vectorDrawable.draw(canvas)
        return BitmapDescriptorFactory.fromBitmap(bitmap)
    }

}// Required empty public constructor

Look at the following snippet

            val googlePlex = CameraPosition.builder()
                .target(LatLng(37.4219999, -122.0862462))
                .zoom(10f)
                .bearing(0f)
                .tilt(45f)
                .build()

            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(googlePlex), 10000, null)

Above lines are making some settings for the google map.

Settings are like latitude, longitude, zoom, tilt etc. You can modify these settings also.

Now focus on the following coding zone

 mMap.addMarker(
                MarkerOptions()
                    .position(LatLng(37.4219999, -122.0862462))
                    .title("Spider Man")
                    .icon(bitmapDescriptorFromVector(activity, R.drawable.spider))
            )

Above coding lines will add one marker on the google map.

.position() will set the position of the marker using latitude and longitude.

.title() will reflect as the name of the marker.

.icon() will allow us to set any image as the icon or view of the marker.

Last Words

You should have two main files like activity_main.xml and MainActivity.kt

Following is the code court for the file activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

        <Button
                android:layout_width="0dp"
                android:layout_weight="1"
                android:id="@+id/btn1"
                android:layout_height="wrap_content"
                android:text="Fragment 1 " />
        <Button
                android:layout_width="0dp"
                android:layout_weight="1"
                android:id="@+id/btn2"
                android:layout_height="wrap_content"
                android:text="Map Fragment" />

    </LinearLayout>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/container_frame_back"
            android:layout_marginTop="5dp"
            android:orientation="horizontal">


    </LinearLayout>

</LinearLayout>

There are two buttons and one Linearlayout is there in the above file.

Linear layout will work as the container of the fragment.

We will load OneFragment and google map inside this linear layout.

Now write down the below coding reference inside the MainActivity.kt file.

import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentTransaction
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button

class MainActivity : AppCompatActivity() {

    private var btn1: Button? = null
    private var btn2: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn1 = findViewById(R.id.btn1) as Button
        btn2 = findViewById(R.id.btn2) as Button

        btn1!!.setOnClickListener { addFragment(OneFragment(), false, "one") }

        btn2!!.setOnClickListener { addFragment(MapFragment(), false, "one") }

    }

    fun addFragment(fragment: Fragment, addToBackStack: Boolean, tag: String) {
        val manager = supportFragmentManager
        val ft = manager.beginTransaction()

        if (addToBackStack) {
            ft.addToBackStack(tag)
        }
        ft.replace(R.id.container_frame_back, fragment, tag)
        ft.commitAllowingStateLoss()
    }
}

When the user clicks the btn1, compiler will load the OneFragment inside the container.

On the click event of the btn2, compiler will load the MapFragment.

Compiler is using the addFragment() method to load the fragment in the container.

Below is the codding snippet for the addFragment() method.

 fun addFragment(fragment: Fragment, addToBackStack: Boolean, tag: String) {
        val manager = supportFragmentManager
        val ft = manager.beginTransaction()

        if (addToBackStack) {
            ft.addToBackStack(tag)
        }
        ft.replace(R.id.container_frame_back, fragment, tag)
        ft.commitAllowingStateLoss()
    }

This method has three parameters. First parameter is the name of the fragment.

Second is the boolean variable one which says whether to put the fragment in the back stack or not.

ft.replace() will put the fragment into the container (container_frame_back)

Download Code From Github

Code From Github