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.
Related
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 recently working on activating SearchView in ActionMode when user click on Search in onOptionsItemSelected.
However, I cant get access to the SearchView as after debugging, its actionView apparently to be null. Can anyone help me with this?
override fun onOptionsItemSelected(item: MenuItem): Boolean {
R.id.chat_search -> {
if (searchActionMode == null) {
searchActionMode = startActionMode(searchActionModeCallBack)
}
}
ActionModeCallBack
private val searchActionModeCallBack = object: ActionMode.Callback {
private lateinit var mSearchView: SearchView
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_search_message, menu)
moreMenuBtn.isVisible = false
layout_chatbox.hide()
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
val searchItem = menu?.findItem(R.id.search_item_btn)
if(searchItem?.actionView != null) { <---- this seachview.actionView keeps return null
mSearchView = searchItem.actionView as SearchView
mSearchView.isIconified = false
mSearchView.onQueryTextChanged { newText ->
}
}
return true
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
when(item?.itemId) {
R.id.search_item_up -> {
"UP".showToast(this#ChatActivity)
}
R.id.search_item_down -> {
"DOWN".showToast(this#ChatActivity)
}
R.id.search_item_btn -> {
"SEARCH".showToast(this#ChatActivity) <-- when click on "Search" Button, "Search" is toasted.
}
}
return false
}
override fun onDestroyActionMode(mode: ActionMode?) {
searchActionMode = null
moreMenuBtn.isVisible = true
layout_chatbox.show()
}
}
menu_search_message.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">
<group android:id="#+id/group_search_mode">
<item
android:id="#+id/search_item_btn"
android:icon="#drawable/ic_baseline_search_24"
app:showAsAction="always"
android:title="#string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView" />
<item
android:id="#+id/search_item_up"
android:icon="#drawable/ic_baseline_arrow_drop_up_24"
app:showAsAction="always"
android:title="#string/up"/>
<item
android:id="#+id/search_item_down"
android:icon="#drawable/ic_baseline_arrow_drop_down_24"
app:showAsAction="always"
android:title="#string/down"/>
</group>
</menu>
I used androidx.appcompat.widget.SearchView for all of the SearchView I used. But still I had no idea why I can't access to the SearchView in ActionMode. Please give me some help.
I faced the same issue before, and what worked for me is to set the ActionView programmatically, not in menu xml.
To do that:
First: Remove the Action ViewClass from your 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">
<group android:id="#+id/group_search_mode">
<item
android:id="#+id/search_item_btn"
android:icon="#drawable/ic_baseline_search_24"
app:showAsAction="always"
android:title="#string/search"/>
...
Second: Create an instance of a SearchView
Third: Inflate the menu item that you want to set its actionViewClass, and use setActionView(view) to set your instantiated SearchView.
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_search_message, menu)
moreMenuBtn.isVisible = false
layout_chatbox.hide()
// Step 2:
val searchView = SearchView(this)
searchView.setQuery(null, true)
searchView.queryHint = "Search"
// Step 3:
val searchItem = menu?.findItem(R.id.search_item_btn)
searchItem.setActionView(searchView)
return true
}
I had a workaround for this.
In my case, I will add a customview to the actionMode's title.
Here is my solution.
override fun onOptionsItemSelected(item: MenuItem): Boolean {
R.id.chat_search -> {
if (searchActionMode == null) {
searchActionMode = startActionMode(searchActionModeCallBack)
val view = layoutInflater.inflate(R.layout.custom_searchview, null)
searchActionMode?.customView = view <-- ADD YOUR CUSTOM VIEW
val etSearch = view.findViewById<EditText>(R.id.et_search)
etSearch.requestFocus()
etSearch.doOnTextChanged { text, start, before, count ->
// TODO - handle the search query here
}
}
}
custom_searchview.xml (Just a simple EditText)
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >
<EditText
android:id="#+id/et_search"
android:layout_alignParentStart="true"
android:maxLines="1"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:padding="10dp"
android:layout_marginEnd="50dp"
android:hint="Search..."
android:textColorHint="#color/colorWhite"
android:textColor="#color/colorWhite"/>
</RelativeLayout>
menu_search_message.xml (REMOVE THE SEARCH VIEW ITEM)
<?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--> <-- remove the searchView from xml
<!-- android:id="#+id/search_item_btn"-->
<!-- android:icon="#drawable/ic_baseline_search_24"-->
<!-- android:title="#string/search"-->
<!-- android:enabled="true"-->
<!-- android:actionLayout="#layout/custom_searchview"-->
<!-- app:showAsAction="collapseActionView|always" />-->
<item
android:id="#+id/search_item_up"
android:icon="#drawable/ic_baseline_arrow_drop_up_24"
android:orderInCategory="2"
android:title="#string/up"
app:showAsAction="always" />
<item
android:id="#+id/search_item_down"
android:icon="#drawable/ic_baseline_arrow_drop_down_24"
android:orderInCategory="3"
android:title="#string/down"
app:showAsAction="always" />
</menu>
Final output will be like this
I have create an Android application using NavigationDrawer. When the application is created, there is one icon menu set by default, placed in the left of the toolBar. And my aim is to add another icon placed, for example, in the right of the toolbar. I have tried many tutorials by following them step by step, by I can't achieve it. Could anyone help me?
in activity
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.game_menu, menu)
return true
}
to handle clicks on menu items
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle item selection
return when (item.itemId) {
R.id.new_game -> {
newGame()
true
}
R.id.help -> {
showHelp()
true
}
else -> super.onOptionsItemSelected(item)
}
}
in menu folder game_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/new_game"
android:icon="#drawable/ic_new_game"
android:title="#string/new_game"
android:showAsAction="always"/> // this icon will be always shown
<item android:id="#+id/help"
android:icon="#drawable/ic_help"// add you icon image
android:title="#string/help"
android:showAsAction="ifRoom"/> // this icon will be shown if there is space available
</menu>
If you are Using Toolbar set as Actionbar (setSupportActionBar(Toolbar)) or Actionbar alone:
In your Activity:
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
getMenuInflater().inflate(R.layout.menu_home, menu)
return true
}
In res -> menu folder add a new file named menu_home (if menu folder does not exists make one):
Add as many items you need to menu_home file:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/item_01"
android:title="#string/my_title"
android:icon="#drawable/my_icon"
app:showAsAction="ifRoom"/>
...
</menu>
showAsAction="ifRoom" makes icon available in Toolbar if there is room for it. you also have an option for never as it goes inside the popup menu.
If you are using Toolbar only (without setting as Actionbar):
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
app:menu="#menu/menu_home"
android:layout_height="?android:attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
You need to create a menu to achieve this task. For example;
res/menu/menu_main.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/new_item"
android:icon="#drawable/new_icon"
app:showAsAction="ifRoom">
</item>
</menu>
If you already have a menu then you can continue with it.
After you have created the menu, you need to inflate it.
public class MainActivity extends AppCompatActivity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
Refer this for more details about using the menu resource: https://developer.android.com/guide/topics/resources/menu-resource
In your menu.xml add :
<item
android:title="icon"
app:showAsAction="always"
android:id="#+id/menuitem_icon"
android:icon="#drawable/micon"
>
</item>
Then in OnCreateView: setHasOptionsMenu(true); Closing the OncreateView below write this method:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.icon, menu);
...
}
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!