Apply a custom style to a Google map

- Posted in Uncategorized by

Customize the styling of the base map using a JSON object defined in a raw resource file.

    private fun setMapStyle(map: GoogleMap) {
        try {
            val success = map.setMapStyle(
                MapStyleOptions.loadRawResourceStyle(
                    this,
                    R.raw.map_style
                )
            )

            if (!success) {
                Log.e(mTAG, "Style parsing failed.")
            }
        } catch (e: Resources.NotFoundException) {
            Log.e(mTAG, "Can't find style. Error: ", e)
        }
    }


Shorter version:

val style = MapStyleOptions.loadRawResourceStyle(
            this, 
            R.raw.default_map_style
            )

mMap.setMapStyle(style)
mMap.mapType = GoogleMap.MAP_TYPE_NORMAL

Add preference fragment and monitor for clicks

- Posted in User Interface by

Add a preference fragment where we inflate our settings screen, then do something if the user clicks on an item inside that screen.

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
26
class MySettingsFragment : PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

        setPreferencesFromResource(R.xml.settings, rootKey)

        val sharedPref = activity?.getPreferences(AppCompatActivity.MODE_PRIVATE) ?: return
        val vNormalMap: Preference? = findPreference(getString(R.string.pNormal_map))

        vNormalMap?.onPreferenceClickListener = Preference.OnPreferenceClickListener {

            it.setIcon(R.drawable.icon_radio_grey)

            with (sharedPref.edit()) {
                putString(getString(R.string.pNormal_map), "newHighScore")
                apply()
            }

            val defaultValue = "resources"
            val highScore = sharedPref.getString(getString(R.string.pNormal_map), defaultValue)
            println("The current value is $highScore")

            true
        }
        
    }
}


Where:

  • 4️⃣ - Create the preference screen from an XML resource
  • 6️⃣ - Declare a preference file where we can save the user's choices
  • 7️⃣ - Specify an item in our XML resource as a preference object
  • 9️⃣ - Listen for clicks on this item

If user clicks, do the following:

  • 1️⃣1️⃣ - Change the icon of the resource
  • 1️⃣3️⃣ ▸ 1️⃣6️⃣ - Set the value of the "pNormalMap" key as "newHighScore"
  • 1️⃣8️⃣ - Set the default value as "resources"
  • 1️⃣9️⃣ - Get the current value of "pNormalMap". If no value set, use the default value
  • 2️⃣0️⃣ - Print the current value to logcat

Show dividers on menu

- Posted in User Interface by

By default, the overflow menu does not support dividers between items. To show dividers on the overflow menu, add the following code:

1
2
3
4
5
6
7
8
9
10
11
12
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        val inflater = menuInflater
        inflater.inflate(R.menu.map_options, menu)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            menu?.setGroupDividerEnabled(true)
        }

        MenuCompat.setGroupDividerEnabled(menu, true)

        return true
    }


Lines 2~3 inflate the menu, while:

  • 5️⃣ - If SDK version supports the divider, enable the .setGroupDividerEnabled
  • 9️⃣ - Load MenuCompat to enable compatibility with lower versions of Android


The end result:

Overflow menu with divider

Change title of Main Activity

- Posted in Uncategorized by

Change the title that appears on the "title bar" of the main activity. By default, the main activity fragment displays the app name. Place this code inside the onCreate block....

Click button to open URL

- Posted in Functions by

Click a button to open URL.

1
2
3
4
5
6
7
8
hBottom.kStreetViewLink.setOnClickListener { 

    val hStreetURL = "YOUR-URL-HERE"
    val openURL = Intent(Intent.ACTION_VIEW) 
    openURL.data = Uri.parse(hStreetURL) 
    startActivity(openURL) 

  }

Where:

1️⃣   Specify the element to monitor, and use the .setOnClickListener event to check if the user clicks the element specified.

3️⃣   Provide the target URL here.


Expected outcome:

  1. Launch the user's default browser.
  2. Go to the target URL using the default browser.

Create a new Constraint layout from scratch

- Posted in Uncategorized by

Create a new constraint layout from scratch.

  • ImageView to add images. Images should already be added to the Resource folder.
  • TextView to add text. Text should ideally be in the strings XML file.
  • app:layout_constraintX_toY property to define the placement of each element. Specify how each element should be placed beside other elements.
  • Button to add a button.
  • View to add empty space.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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_margin="10dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


    <ImageView
        android:id="@+id/kInfo"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:scaleX="0.7"
        android:scaleY="0.7"
        app:layout_constraintRight_toLeftOf="@+id/kInfoView"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/icon_info"
        android:contentDescription="@string/infoIcon" />
    <TextView
        android:id="@+id/kInfoView"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:padding="3dp"
        android:textStyle="bold"
        android:textColor="@color/silver"
        app:layout_constraintLeft_toRightOf="@+id/kInfo"
        app:layout_constraintTop_toTopOf="parent"
        android:text="@string/information" />


    <ImageView
        android:id="@+id/kAddress"
        android:layout_width="24dp"
        android:layout_height="34dp"
        android:scaleX="1"
        android:scaleY="1"
        app:layout_constraintRight_toLeftOf="@+id/kAddress_Line"
        app:layout_constraintTop_toTopOf="@id/kAddress_Line"
        app:srcCompat="@drawable/icon_map"
        android:contentDescription="@string/addressLine" />
    <TextView
        android:id="@+id/kAddress_Line"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:padding="3dp"
        android:textSize="20sp"
        app:layout_constraintLeft_toRightOf="@+id/kAddress"
        app:layout_constraintTop_toBottomOf="@id/kInfoView"
        android:text="@string/addressLine" />


    <ImageView
        android:id="@+id/kNotes"
        android:layout_width="24dp"
        android:layout_height="34dp"
        android:scaleX="1"
        android:scaleY="1"
        android:contentDescription="@string/pinIcon"
        app:layout_constraintRight_toLeftOf="@+id/kNoteContent"
        app:layout_constraintTop_toTopOf="@id/kNoteContent"
        app:srcCompat="@drawable/icon_notes" />
    <TextView
        android:id="@+id/kNoteContent"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:padding="3dp"
        android:textSize="20sp"
        app:layout_constraintLeft_toRightOf="@+id/kNotes"
        app:layout_constraintTop_toBottomOf="@id/kAddress_Line"
        android:text="@string/noteContent" />


    <Button
        android:id="@+id/kStreetViewLink"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:text="@string/goToStreetView"
        app:layout_constraintTop_toBottomOf="@id/kNoteContent"
        app:layout_constraintStart_toStartOf="@id/kNoteContent" />

    <View
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:layout_constraintTop_toBottomOf="@id/kStreetViewLink" />

</androidx.constraintlayout.widget.ConstraintLayout>

This is how it looks like:

Screenshot of new constraint layout