1

I've got a Popup menu that should launch a Maps intent whenever a Popup menu item is clicked. In popupMenu.setOnMenuItemClickListener, does anyone know how I can pass the String of the clicked Popup menu item (from the arrayAMap array) and use it for an intent? I've already got the Arrays but I can't seem to figure out that correct way to implement this function.

class MyAdapter(
    private val mCtx: Context,
    var myList: MutableList<ItemRV>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), PopupMenu.OnMenuItemClickListener {
    private var mClickListener: ItemClickListener? = null

    lateinit var mAdView : AdView

    private val itemRV = 1
    private val itemAD = 2

    override fun getItemViewType(position: Int): Int {
        return if (position % 4 == 0) {
            itemAD
        } else {
            itemRV
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return if (viewType == itemAD) {
            val v = LayoutInflater.from(mCtx).inflate(R.layout.item_ad, parent, false)
            AdViewHolder(v)
        } else {
            val v = LayoutInflater.from(mCtx).inflate(R.layout.item_rv, parent, false)
            AreaViewHolder(v)
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when(holder) {
            is AdViewHolder -> {
                MobileAds.initialize(mCtx) {}
                mAdView = holder.itemView.findViewById(R.id.adView)
                val adRequest = AdRequest.Builder().build()
                mAdView.loadAd(adRequest)
            }

            is AreaViewHolder -> {
            val positionToBind = position - position / 4 - 1
            val product = myList[positionToBind]
            holder.tvTitle.text = product.itemTitle
            }
        }
    }

    override fun getItemCount(): Int {
        return myList.size
    }


    inner class AdViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
    .ViewHolder(itemView), View.OnClickListener {
        override fun onClick(v: View?) {
        }
    }

    inner class AreaViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
    .ViewHolder(itemView), View.OnClickListener {
        var tvTitle: TextView = itemView.tvtitle

        // Use package name which we want to check
        private val isAppInstalled = appInstalledOrNot("com.google.android.apps.maps")
        private val isLiteAppInstalled = appInstalledOrNot("com.google.android.apps.mapslite")

            fun launchMapIntent(nameLocation: String) {
                val mapPkg = when {
                    isAppInstalled -> "com.google.android.apps.maps"
                    isLiteAppInstalled -> "com.google.android.apps.mapslite"
                    else -> null
                }
                val mapIntent = if(mapPkg != null) {
                    val gmmIntentUri = Uri.parse("geo:0,0?q=$nameLocation")
                    Intent(Intent.ACTION_VIEW, gmmIntentUri).setPackage(mapPkg)
                } else {
                    val encLoc = Uri.encode(nameLocation)
                    val str = "https://www.google.com/maps/place/$encLoc/"
                    Intent(Intent.ACTION_VIEW, Uri.parse(str))
                }
                mCtx.startActivity(mapIntent)
            }

            val arrayA = arrayOf(view.resources.getString(R.string.stockholm),
                view.resources.getString(R.string.copenhagen))
            val arrayAMap = arrayOf("Stockholm, Sweden", "Copenhagen, Denmark")

            fun launchPopupMenu(namePopupItemLocation: Array<String>, nameLocation: Array<String>){
                val popupMenu = PopupMenu(ibMap.context, ibMap)

                for (item in namePopupItemLocation) {
                    popupMenu.menu.add(item)
                }

                popupMenu.setOnMenuItemClickListener {
                  launchMapIntent(nameLocation.get())
                    true
                }

                popupMenu.show()
            }

            ibMap.setOnClickListener {
                when(tvTitle.text.toString()) {
                    "A" -> launchMapIntent("Paris, France")
                    "B" -> launchPopupMenu(arrayA, arrayAMap)

                    else -> return@setOnClickListener
                }
            }
        }


        private fun appInstalledOrNot(uri: String): Boolean {
            val pm = mCtx.packageManager
            try {
                pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
                return true
            } catch (e: PackageManager.NameNotFoundException) {
            }
            return false
        }

    }

    // Parent activity will implement this method to respond to click events
    interface ItemClickListener {
        fun onItemClick(view: View, position: Int)
    }

    override fun onMenuItemClick(item: MenuItem?): Boolean {
    }
}
wbk727
  • 8,017
  • 12
  • 61
  • 125

1 Answers1

3

You can get clicked menu item in setOnMenuItemClickListener and from that menu item you can get title of that menu

 popupMenu.setOnMenuItemClickListener { item ->
            nameLocation.forEach {
                if (it.toLowerCase().startsWith(item.title.toLowerCase())) {
                    launchMapIntent(it)
                }
            }
            true
        }

Hope this will help!!

Nehal Godhasara
  • 787
  • 3
  • 7
  • I'm not looking for an item ID, I want to check for a String – wbk727 Jan 28 '20 at 11:42
  • There is already string also, you can use that menuTitle variable. – Nehal Godhasara Jan 28 '20 at 11:44
  • What is `menuTitle`? That's obviously going to appear in grey as never used. – wbk727 Jan 28 '20 at 11:46
  • yes you can use that menuTitle as per your requirement, its just a suggestions, how you can get menu title from clicked menu. – Nehal Godhasara Jan 28 '20 at 11:47
  • I don't want the menu title, I want the popup menu item title (e.g. `view.resources.getString(R.string.stockholm)`). Several different arrays will be used in future + the popup menu items are added dynamically so I don't think this answer will work. – wbk727 Jan 28 '20 at 11:50
  • @MacaronLover I have tried for menu item added dynamically, its working perfectly and giving title for clicked menu. – Nehal Godhasara Jan 28 '20 at 11:57
  • I still don't understand what `menuTitle` is supposed to be. When I use `R.id.` I can't use the name of my `String`. It is expecting a menu item name rather than a `String` name. I can't provide a menu item name when those were declared programmatically from a loop. – wbk727 Jan 28 '20 at 12:38
  • I think you are confused from example, so I simplified and edited my answer, Please check and let me know if it works. – Nehal Godhasara Jan 28 '20 at 12:44
  • Ok, this works and is easier to read but how can I use a value within the other `Array` I ccreated? i.e. `arrayAMap`? – wbk727 Jan 28 '20 at 14:32
  • This what I asked for orignally but if this is not possible, please let me know :-) – wbk727 Jan 29 '20 at 09:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/206838/discussion-between-nehal-godhasara-and-macaronlover). – Nehal Godhasara Jan 29 '20 at 09:42