Kotli N — how To Create A Custom Toast

Kotli N — how To Create A Custom Toast

In this example I will be explaining how to make a toast in two different ways. The first way be a very easy way while the second way will be not so easy, because we will be using lambda expression. But first you have to create project. Create a new project and when you are through compare your activity_main.xml with mine and make sure you are not missing anything. Your activity_main.xml should look something like this

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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">
    <Button
        android:id="@+id/id_btn_show_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/show_toast"
        android:layout_gravity="center"/>
</FrameLayout>

if your android:text=”@string/show_toast” is displaying an error just change it to android:text=”Show Toast” and that should fix it. You should also compare your MainActivity.kt with mine and make sure you are not missing anything. Your MainActivity.kt should look something like this

class MainActivity : AppCompatActivity() {
    private lateinit var id_btn_show_toast: Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        id_btn_show_toast = findViewById(R.id.id_btn_show_toast)
        clickButtonListener()
    }

    private fun clickButtonListener() {
        id_btn_show_toast.setOnClickListener{
            Tool.showToast(this, "This is a toast message", Gravity.TOP)
        }
    }
}

Do not worry if your 'Tool' is displaying an error, we will fix it. Before we do that we will create a layout called toast_popup. Create a layout called toast_popup.xml and it should look something like this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="20dp"
    android:id="@+id/id_ll_toast_layout">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/id_tv_toast_message"
        android:text="@string/app_name"
        android:gravity="center_vertical"
        app:drawableStartCompat="@drawable/ic_toast" />
</LinearLayout>

I added an ic_toast drawable which is an image to the TextView. This can only work if your TextView is inside a LinearLayout. The LinearLayout and the TextView has an id so we can use them inside the toast.

Now to fix the Tool error we had earlier. Create an object class called Tool. To do that create a kotlin class and set is as an object class like this

object Tool {

    fun showToast(activity: Activity, message: String, gravity: Int = Gravity.BOTTOM){
        // Get the toast layout
        val layout = LayoutInflater.from(activity)
            .inflate(R.layout.toast_popup, activity.findViewById(R.id.id_ll_toast_layout))
        // Initialize the textview to show message
        val id_tv_toast_message: TextView = layout.findViewById(R.id.id_tv_toast_message)
        // Add the message to the textview
        id_tv_toast_message.text = message
        // Configure the toast to show the custom toast
        Toast(activity).apply {
            this.view = layout
            this.duration = Toast.LENGTH_SHORT
            this.setGravity(gravity,0,40)
        }.show()
    }

    fun advanceShowToast(activity: Activity, message: String, gravity: Int = Gravity.BOTTOM, function: ((TextView) -> Unit)?){
        // Get the toast layout
        val layout = LayoutInflater.from(activity).inflate(R.layout.toast_popup, activity.findViewById(R.id.id_ll_toast_layout))
        // Initialize the text view to show message
        val id_tv_toast_message: TextView = layout.findViewById(R.id.id_tv_toast_message)
        // Add the message to the textview
        id_tv_toast_message.text = message
        // Lambda function to manipulate the textview
        function!!(id_tv_toast_message)
        // Configure the toast to show the custom toast
        Toast(activity).apply {
            this.view = layout
            this.duration = Toast.LENGTH_SHORT
            this.setGravity(gravity,0,40)
        }.show()
    }
}

FIRST METHOD The first function showToast() in the Tool object class has a parenthesis called ‘activity’ which will hold the current activity that our toast will be using. The message hold the message that will be displayed obviously, while the gravity makes the toast display where we wan it to display. the default is set to BOTTOM.

Then we created a LayoutInflater that will display the toast. we create the LayoutInflater with the activity, the toast_popup.xml layout file we created, and the LinearLayout view inside the toast_popup. You can also inflate your layout without using a LinearLayout like this, ‘inflate(R.layout.toast_popup, null)’ but android studio will complain.

Then we Initialize the TextView we created inside the toast_popup.xml and set the message in the parenthesis to it, finally we created a toast instance. you can either do it like this

Toast(activity).apply {
    this.view = layout
    this.duration = Toast.LENGTH_SHORT
    this.setGravity(gravity,0,40)
}.show()

or like this

val toast = Toast(activity)
toast.view = layout
toast.duration = Toast.LENGTH_SHORT
toast.setGravity(gravity,0,40)
toast.show()

either way works... SECOND METHOD The second method is just like the first method, but it give us more customization power because of its lambda function. The second function named advanceShowToast() has a lambda as part of its parenthesis We created a lambda function that expect null as a value, that is why it looks like funny, this gives us the choice to use or not use the lambda function, and the way we use the lambda inside the advanceShowToast() is by asserting it to null, you can do it like this

function!!(id_tv_toast_message)

or like this

if (function != null) {
    function(id_tv_toast_message)
}

or like this

function?.let { it(id_tv_toast_message) }

USING THE showToast METHOD You can use the showToast function in the MainActivity like this

Tool.showToast(this, "This is a toast message", Gravity.BOTTOM)

or

Tool.showToast(this, "This is a toast message")

we did not add gravity because Gravity has a default value so it can be ignored USING THE advanceShowToast METHOD You can use the advanceShowToast function in the MainActivity like this

Tool.advanceShowToast(this, "This is a toast message", Gravity.BOTTOM, null)

or

Tool.advanceShowToast(this, "This is a toast message", function = null)
Tool.advanceShowToast(this, "This is a toast message", Gravity.CENTER){ textview ->
    textview.setBackgroundColor(Color.YELLOW)
    textview.setTextColor(Color.BLACK)
}

lastly like this

Tool.advanceShowToast(this, "This is a toast message"){ textview ->
    textview.setBackgroundColor(Color.YELLOW)
    textview.setTextColor(Color.BLACK)
}

our lambda function named function is set to null because we do not want to use it. our gravity already has a default value so we can ignore it’s declarations

FINNALLY If you are in a fragment you can use of the functions like this

Tool.showToast(requireActivity(), "This is a toast message", Gravity.TOP)
Tool.showToast(requireActivity(), "This is a toast message")

or

Tool.advanceShowToast(requireActivity(), "This is a toast message", Gravity.TOP, null)

or

Tool.advanceShowToast(requireActivity(), "This is a toast message", function = null)
Tool.advanceShowToast(requireActivity(), "This is a toast message", Gravity.CENTER){ textview ->
    textview.setBackgroundColor(Color.YELLOW)
    textview.setTextColor(Color.BLACK)
}

or

Tool.advanceShowToast(requireActivity(), "This is a toast message"){ textview ->
    textview.setBackgroundColor(Color.YELLOW)
    textview.setTextColor(Color.BLACK)
}