Thursday, June 11, 2020

android kotlin - Popup menu with icons

MainActivity.kt

package com.example.jetpack

import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.widget.PopupMenu
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.reflect.Method


class MainActivity : AppCompatActivity() {

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

        // show sdk version in text view
        textView.append("\nAPI " + Build.VERSION.SDK_INT)

        // text view click listener
        textView.setOnClickListener {
            showPopupMenu()
        }
    }


    // method to show popup menu
    private fun showPopupMenu(){
        val popup = PopupMenu(this,textView)

        popup.apply {
            // inflate the popup menu
            menuInflater.inflate(R.menu.popup_menu,menu)

            // popup menu item click listener
            setOnMenuItemClickListener {
                when(it.itemId){
                    R.id.red->{
                        textView.setTextColor(Color.RED)
                    }R.id.green->{
                        textView.setTextColor(Color.GREEN)
                    }R.id.yellow->{
                        textView.setTextColor(Color.YELLOW)
                    }R.id.gray->{
                        textView.setTextColor(Color.GRAY)
                    }
                }

                false
            }
        }

        // show icons on popup menu
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            popup.setForceShowIcon(true)
        }else{
            try {
                val fields = popup.javaClass.declaredFields
                for (field in fields) {
                    if ("mPopup" == field.name) {
                        field.isAccessible = true
                        val menuPopupHelper = field[popup]
                        val classPopupHelper =
                            Class.forName(menuPopupHelper.javaClass.name)
                        val setForceIcons: Method = classPopupHelper.getMethod(
                            "setForceShowIcon",
                            Boolean::class.javaPrimitiveType
                        )
                        setForceIcons.invoke(menuPopupHelper, true)
                        break
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        // finally, show the popup menu
        popup.show()
    }
}
activity_main.xml

<?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:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/textView"
        style="@style/TextAppearance.MaterialComponents.Headline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="11dp"
        android:text="Show Popup Menu"
        android:background="#F6F6F2"
        android:padding="5dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
res/menu/popup_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/red"
        android:title="Red"
        android:icon="@drawable/ic_camera"
        android:iconTint="#F44336"
        android:iconTintMode="src_in"
        />
    <item
        android:id="@+id/green"
        android:title="Green"
        android:icon="@drawable/ic_donut_large"
        android:iconTint="#4CAF50"
        android:iconTintMode="src_in"
        />
    <item
        android:id="@+id/yellow"
        android:title="Yellow"
        android:icon="@drawable/ic_dock"
        android:iconTint="#FFEB3B"
        android:iconTintMode="src_in"
        />
    <item
        android:id="@+id/gray"
        android:title="Gray"
        android:icon="@drawable/ic_add_circle"
        android:iconTint="#707070"
        android:iconTintMode="src_in"
        />
</menu>