Declare a fragment

- Posted in Uncategorized by

To simply declare a fragment that you can call later in your code:

class SecondFragSampleName : Fragment(R.layout.second_fragment)


or if you want to specify extra methods that will run when the fragment becomes active.

class SecondFragSampleName : Fragment(R.layout.second_fragment) {
  // Declare methods here, ie, OnCreate, etc.
}


Notes:

  • Do not declare this inside the main activity fragment. Suggested placement is after the main activity fragment.
  • Ensure that a second_fragment layout exists, and that it contains the androidx.fragment.app.FragmentContainerView element.


Then when you want to switch to this "second fragment", add the following code as an action/method on the currently active fragment:

supportFragmentManager
    .beginTransaction()
    .setTransition(TRANSIT_FRAGMENT_OPEN)
    .setReorderingAllowed(true)
    .addToBackStack("DefaultView")
    .add(R.id.map, SecondFragSampleName())
    .commit()

Create a snackbar

- Posted in Uncategorized by

Kotlin code to create and configure a snackbar:

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
27
28
29
30
31
32
33
34
    // Run this action if user clicks on snackbar Action Text
    class CustomSnackBarAction : View.OnClickListener {
        override fun onClick(v: View) {
            oToast("This device is not supported.")
           }
        }

    // Declare snackbar variables
    val currentView: View = this.findViewById(android.R.id.content)
    val snackBar = Snackbar.make(
        currentView,
        "This text will appear on the snackbar.",
        Snackbar.LENGTH_INDEFINITE
        )

    // Specify how Action Text should look and behave
    snackBar.setAction("OK", CustomSnackBarAction())
    snackBar.setActionTextColor(Color.WHITE)
    snackBar.setTextColor(Color.YELLOW)
    snackBar.setMaxInlineActionWidth(500)

    // Configure background of the snackbar
    val snackBarView = snackBar.view
    snackBarView.setBackgroundColor(Color.DKGRAY)

    // Configure text on the snackbar
    val textView =
        snackBarView.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
    textView.setTextColor(Color.YELLOW)
    textView.textSize = 28f
    textView.maxLines = 5

    // Show the snackbar
    snackBar.show()


Where:

  • 2️⃣ - Declare a function that runs whenever the user clicks the Action Text on the snackbar
  • 4️⃣ - This is a custom function to generate a Toast message.
  • 9️⃣ - Find current view and assign it to a variable
  • 🔟 - Create a snackbar, but don't show it yet
  • 1️⃣3️⃣ - Specify Snackbar.LENGTH_INDEFINITE so snackbar does not go away until user clicks the Action Text
  • 1️⃣7️⃣ - Set the custom action that occurs if users click the Action Text
  • 2️⃣4️⃣ - Set a custom bgcolor for the snackbar
  • 2️⃣7️⃣ - Find snackbar text so we can modify its style
  • 3️⃣1️⃣ - Number of maximum lines that the snackbar supports. If not set, Android Studio uses the default value of 1and will only show the text on one line.
  • 3️⃣4️⃣ - Show the snackbar to the world

Private function for toast

- Posted in Uncategorized by

Created a private function so I don't need to write very long and verbose syntax just to show a Toast. private fun oToast(text: String) {...

Check if Google Play Services is available

- Posted in Uncategorized by

Check if Google Play Services is available.

private fun checkPlayServices(): Boolean {
    val apiAvailability = GoogleApiAvailability.getInstance()
    val resultCode = apiAvailability.isGooglePlayServicesAvailable(this)

    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
              // Do stuff if Google Play is not available 
        } else {
              // Do stuff if Google Play is available 
            finish()
        }
        return false
    }
    return true
}

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