I want to add click event when I click on one of the item in navigation drawer, I have used onNavigationItemSelected method but it's not working, Any help?
override fun onNavigationItemSelected(item: MenuItem): Boolean {
TODO("Not yet implemented")
val id = item.itemId
if (id == R.id.nav_signout) {
Toast.makeText(this, "Sign out", Toast.LENGTH_SHORT).show()
}
return true
}
drawer.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item android:title="Authentication">
<menu android:checkableBehavior="all">
<item
android:id="#+id/nav_signout"
android:icon="#drawable/ic_menu_gallery"
android:title="Sign out" />
</menu>
</item>
</group>
</menu>
Since you are overriding onNavigationItemSelected I suppose you implemented NavigationView.OnNavigationItemSelectedListener directly to your activity/fragment.
Make sure you added it to your navigation when it is created
navigation_view.setNavigationItemSelectedListener(this)
Or other option would be to implement it directly to your navigation instead of activity/fragment. Remove code you posted and activity/fragment implementation and use kotlin lambdas like this
navigation_view.setNavigationItemSelectedListener{
TODO("Not yet implemented")
val id = item.itemId
if (id == R.id.nav_signout) {
Toast.makeText(this, "Sign out", Toast.LENGTH_SHORT).show()
}
return true
}
Related
I have the following main menu drawer, where the "Home button" is static, but the elements under "Read groups" are dynamically added. As you can see, the Home menu is properly checked (selected).
The groups all navigate to the same fragment (GroupsShowFragment), but with different parameters. The problem is, that if I navigate to such a group, the menu item selection is not updated (the Home selection even stays active).
Below the drawer_menu.xml code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view"
>
<group android:checkableBehavior="single">
<item
android:id="#+id/menu_nav_home"
android:icon="#drawable/ic_action_home"
android:title="Home" />
</group>
<group android:checkableBehavior="single" android:id="#+id/groups_sub_holder">
<item
android:id="#+id/groups_holder"
android:title="Read groups">
<menu>
</menu>
</item>
</group>
<item android:title="Controls">
<menu>
<group android:checkableBehavior="single">
<item
android:id="#+id/menu_nav_group_add"
android:icon="#drawable/ic_action_add_group"
android:title="#string/fragment_title_groups_add" />
<item
android:id="#+id/menu_nav_settings"
android:icon="#drawable/ic_action_settings"
android:title="Settings" />
</group>
</menu>
</item>
</menu>
The code used to dynamicly add the read groups (data is coming from a Room database):
// Add menu source: https://stackoverflow.com/a/31722855/1175881
val navigationView: NavigationView = findViewById <NavigationView> (R.id.nav_view)
val menu: Menu = (navigationView.menu.findItem(R.id.groups_holder)).subMenu
menu.clear()
// adding a section and items into it
val allGroups: List<Groups> = GroupsManager.getAllGroups()
allGroups.forEach{
it.uid?.let { it1 -> menu.add(0, it1, 0, it.name) }
}
And the code which is handling the "navigation":
private fun handleNavigateTrigger(menuId: Int){
when(menuId) {
R.id.menu_nav_home -> {
homeFragment = HomeFragment()
showFragment(homeFragment)
}
R.id.menu_nav_settings -> {
settingsFragment = SettingsFragment()
showFragment(settingsFragment)
}
R.id.menu_nav_group_add -> {
groupsAddFragment = GroupsAddFragment()
showFragment(groupsAddFragment)
}
else -> {
groupsShowFragment = GroupsShowFragment.newInstance(menuId)
showFragment(groupsShowFragment)
val navigationView: NavigationView = findViewById <NavigationView> (R.id.nav_view)
Log.e("handleNavigateTrigger", "setCheckedItem($menuId)")
navigationView.setCheckedItem(menuId)
}
}
_drawerLayout.closeDrawer(GravityCompat.START)
}
private fun showFragment(fragment: androidx.fragment.app.Fragment){
supportFragmentManager
.beginTransaction()
.replace(R.id.frame_layout, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit()
}
The log does show the correct id's (at least the correct integers) used, so I'm a bit lost here. I've added the group with android:checkableBehavior="single" like this, even as whole menu parent, but to no avail. I'm feeling like I miss one small but very important step, but can't find what that is..
This is a self-answer, but wanted to share the found solution for anybody in the future (can only accept this answer in 2 days, so I'll get back to do that)
I've finally stumbled on this SO answer by Danial B.
Using only the setChecked resulted in a partial (but not sufficient and correctly working) checked menu item. I had to make sure that the menu item was checkable with setCheckable. This resulted in the following code for me:
val navigationView: NavigationView = findViewById <NavigationView> (R.id.nav_view)
val groupItem: MenuItem = navigationView.menu.findItem(menuId)
groupItem.isCheckable = true
groupItem.isChecked = true
I have extended the res/menu/web with a logout option:
<?xml version="1.0" encoding="utf-8"?>
<menu 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">
<item
android:id="#+id/menu_progress"
android:title="#string/loading"
android:visible="false"
app:actionLayout="#layout/toolbar_progress"
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
<item
android:id="#+id/logoutButton"
android:title="Logout"
app:showAsAction="always"/>
</menu>
In the WebFragment I want to handle the logout, but the action is not being called. I'm trying this by doing:
private fun setupMenu() {
toolbarForNavigation()?.inflateMenu(R.menu.web)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
Log.d("WebFragment", "Options item selected")
return when (item.itemId) {
R.id.logoutButton -> {
Log.i("WebFragment", "Logout button pressed")
requireActivity().startNewActivity(PasswordActivity::class.java)
true
}
else -> super.onOptionsItemSelected(item)
}
}
I have tried solving this by checking this StackOverflow topic, but no luck. Therefor, I am wondering if it is even possible with this package.
I created a options menu in my toolbar which shows up with 3 dots icon. I has 2 problems. First, it's not looking like options menu in other apps (text misaligned) and when I run the app on phone it doesn't responds to touch, even the ripples don't show up. On the other hand options menu works when I run it in the emulator(Pixel 2 API 24)
Here's my MainActivity code:
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.options_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.option_about -> {
Toast.makeText(this, "About", Toast.LENGTH_SHORT).show()
return true
}
R.id.option_exit -> {
Toast.makeText(this, "Exit", Toast.LENGTH_SHORT).show()
return true
}
else -> super.onOptionsItemSelected(item)
}
}
Here is the options_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search"
android:icon="#drawable/ic_search_primary"
android:title="#string/search_title"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="#+id/option_about"
android:title="About"
app:showAsAction="never" />
<item
android:id="#+id/option_exit"
android:title="Exit"
app:showAsAction="never" />
</menu>
Actually, I was using wrong popupTheme in my toolbar.
I have created a menu icon on action bar. When it is clicked, I expect it will show something like this
But it display on the left hand side instead.
What could be this issue ?
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
inflater!!.inflate(R.menu.fragment_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.getItemId()
if (id == R.id.more) {
var popup: PopupMenu? = PopupMenu(context!!, view!!)
popup?.menuInflater?.inflate(R.menu.pop_up_menu, popup.menu)
popup?.show()
popup?.setOnMenuItemClickListener({ item: MenuItem? ->
when (item!!.itemId) {
R.id.logOut -> {
}
}
true
})
} else
super.onOptionsItemSelected(item)
return true
}
fragment_menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/more"
android:title="menu"
app:showAsAction="always"
android:icon="#drawable/ic_more"/>
</menu>
pop_up_menu
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/logOut"
app:showAsAction="always"
android:title="Log Out"
/>
</menu>
The view I passing is this
#Nullable
public View getView() {
return this.mView;
}
You are passing the wrong view as what #CodeRed mentioned.
Replace
var popup: PopupMenu? = PopupMenu(context!!, view!!)
to
val vItem = getActivity().findViewById<View>(R.id.more)
var popup: PopupMenu? = PopupMenu(context!!, vItem)
Menu in ActionBar is populated automatically by system, you don't need to write code to populate it.
To achieve the menu like figure 1, fragment_menu should be like:
<menu>
<item android:title="Search" />
<item android:title="Locate" />
<item android:title="Refresh" />
<item android:title="Help" />
<item android:title="Check for update" />
</menu>
onOptionItemSelected is used to handle when above menu is clicked, not used to show the menu.
popup menu is free position menu like right click menus in windows, not the one you expect in figure 1.
I have a searchview in my menu (toolbar). It performs a search query in my recycler view and it works fine. I need to add a custom search suggestions to my searchview and I can't find any way to add it to a default searchview menu item. I have shared the code of my menu items and search query.
Menu XML file:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/actionSearch"
android:title=""
android:icon="#drawable/ic_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView"/>
<item
android:id="#+id/actionAdd"
android:title=""
android:icon="#drawable/ic_add"
app:showAsAction="always|collapseActionView"/>
<item
android:id="#+id/actionImport"
android:orderInCategory="100"
android:title="Import from phone"
app:showAsAction="never"/>
<item
android:id="#+id/actionExport"
android:orderInCategory="100"
android:title="Export as VCF"
app:showAsAction="never" />
<item
android:id="#+id/actionSettings"
android:orderInCategory="100"
android:title="Settings"
app:showAsAction="never" />
</menu>
Search Query:
private fun search(searchView: SearchView) {
searchView.queryHint = "Search Here"
searchView.setIconifiedByDefault(false)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean = false
override fun onQueryTextChange(newText: String): Boolean {
initRecentRecyclerView()
mAdapter2.getFilter().filter(newText)
recentAdapter.getFilter().filter(newText)
return true
}})
MenuItemCompat.setOnActionExpandListener(search, object : MenuItemCompat.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
initRecentRecyclerView()
return true
}
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
recentRecyclerView.visibility = View.GONE
return true
}
})
searchView.setOnFocusChangeListener({ _: View, b: Boolean ->
if(!b){
recentRecyclerView.visibility = View.GONE
}
})
searchView.setOnCloseListener{
recentRecyclerView.visibility = View.GONE
true
}
searchView.setOnQueryTextFocusChangeListener({ view: View, b: Boolean ->
if(!b){
try {
recentRecyclerView.visibility = View.GONE
}catch(e: Exception){}
}
})
}
actionSearch is the id of my searchView, searchView is the reference I have used in my kotlin code. I need to show a list of suggestions in my searchview. Hope that someone can help me out!