I am trying to display a Popup menu on the click of an action bar Icon.
The problem is that I get a forced close of the app and the Popup menu does not display. What is wrong with my code? Thank you for your help.
#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_action, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
Toast.makeText(getApplicationContext(), "ItemSelected = " + item, Toast.LENGTH_SHORT).show();
case R.id.action_sort:
showPopup(item.getActionView());
}
return super.onOptionsItemSelected(item);
}
public void showPopup(View v) {
PopupMenu popup = new PopupMenu(this, v);
Toast.makeText(getApplicationContext(), "showPopup = " + popup, Toast.LENGTH_SHORT).show();
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
}
menu_action.xml
<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" tools:context=".FileManagerActivity">
<item android:id="#+id/action_sort" android:title="#string/action_sort" android:icon="#drawable/ic_sort"
android:showAsAction="always" />
<item android:id="#+id/action_settings" android:title="#string/action_settings"
app:showAsAction="never" />
<item android:id="#+id/action_help" android:title="#string/action_help"
app:showAsAction="never" />
</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/opt1"
android:icon="#drawable/ic_sort"
android:title="Change Picture" />
<item
android:id="#+id/opt2"
android:icon="#drawable/ic_fast_forward"
android:title="Change Password" />
<item
android:id="#+id/opt3"
android:icon="#drawable/ic_fast_rewind"
android:title="Sign Out" />
</menu>
Logcat:
02-28 13:04:45.353 18838-18838/com.test.audio E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.test.audio, PID: 18838
java.lang.IllegalStateException: MenuPopupHelper cannot be used without an anchor
at android.support.v7.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:126)
at android.support.v7.widget.PopupMenu.show(PopupMenu.java:193)
at com.test.audio.TouchActivity.showPopup(TouchActivity.java:5340)
at com.test.audio.TouchActivity.onOptionsItemSelected(TouchActivity.java:5270)
at android.app.Activity.onMenuItemSelected(Activity.java:2885)
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1133)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:904)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:894)
at android.widget.ActionMenuView.invokeItem(ActionMenuView.java:587)
at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:141)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
don't pass MenuItem as View cause it s not.
so it s better to cast it as view like this
View menuItemView = findViewById(R.id.menu_overflow); // SAME ID AS MENU ID
PopupMenu popupMenu = new PopupMenu(this, menuItemView);
popupMenu.inflate(R.menu.counters_overflow);
// And define click listener here.
popupMenu.show();
Source
Related
I have a Options menu with sub-item menus
My app crashes when I click on the option menu, but I can't decrypt logs
I want to have a option button who open 3 option menu subitems
I have checked few tutorials but I can't see where i'm wrong
<?xml version="1.0" encoding="utf-8"?>
<item
android:id="#+id/search_button_main_activity"
android:icon="#drawable/search_button"
android:title="#string/search_button"
app:showAsAction="ifRoom"/>
<item
android:id="#+id/notifications_button"
android:title="#string/notifications_button"
app:showAsAction="never" />
<item
android:id="#+id/help_button"
android:orderInCategory="100"
android:title="#string/help_button"
app:showAsAction="never" />
<item
android:id="#+id/about_button"
android:orderInCategory="100"
android:title="#string/about_button"
app:showAsAction="never" />
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_activity_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search_button_main_activity:
this.launchSearchActivity();
return true;
case R.id.notifications_button:
Toast.makeText(this, "This will launch notification feature", Toast.LENGTH_SHORT).show();
return true;
case R.id.about_button:
Toast.makeText(this, "This will launch about feature", Toast.LENGTH_SHORT).show();
return true;
case R.id.help_button:
Toast.makeText(this, "This will launch help feature", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
here's error message :
2019-07-01 16:12:46.581 com.matt.android.mynews E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.matt.android.mynews, PID: 7624
android.view.InflateException: Binary XML file line #51: Binary XML file line #51: Error inflating class TextView
Caused by: android.view.InflateException: Binary XML file line #51: Error inflating class TextView
Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 4: TypedValue{t=0x2/d=0x1010099 a=1}
at android.content.res.TypedArray.getColor(TypedArray.java:461)
at android.widget.TextView.<init>(TextView.java:771)
at android.widget.TextView.<init>(TextView.java:704)
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:87)
at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:83)
at android.support.v7.app.AppCompatViewInflater.createTextView(AppCompatViewInflater.java:177)
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:102)
at android.support.v7.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1266)
at android.support.v7.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1316)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:794)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:752)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:883)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:846)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:886)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:846)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:886)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:846)
at android.view.LayoutInflater.inflate(LayoutInflater.java:522)
at android.view.LayoutInflater.inflate(LayoutInflater.java:430)
at android.support.v7.view.menu.MenuAdapter.getView(MenuAdapter.java:94)
at android.support.v7.view.menu.MenuPopup.measureIndividualMenuWidth(MenuPopup.java:161)
at android.support.v7.view.menu.StandardMenuPopup.tryShow(StandardMenuPopup.java:174)
at android.support.v7.view.menu.StandardMenuPopup.show(StandardMenuPopup.java:208)
at android.support.v7.view.menu.MenuPopupHelper.showPopup(MenuPopupHelper.java:290)
at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:177)
at android.support.v7.widget.ActionMenuPresenter$OpenOverflowRunnable.run(ActionMenuPresenter.java:806)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6228)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
Logs can't tell me where the crash come from
The error you're getting is not from the menu. It's most probably from the layout you're calling in launchSearchActivity.
As I understand what you want is something like below
You can have a menu like that with the xml given below(Please change the drawables, names and ids as you want)
<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" tools:context=".MainActivity">
<item
android:id="#+id/action_rate" android:title="#string/action_rate"
android:icon="#drawable/ic_favorite_border_black_24dp" app:showAsAction="always|withText"/>
<item
android:icon="#drawable/ic_more_vert_black_24dp"
android:title="More"
app:showAsAction="always">
<menu>
<item android:id="#+id/action_contact_us" android:icon="#drawable/ic_email_black_24dp"
android:title="#string/action_about"
android:orderInCategory="102" app:showAsAction="never"/>
<item android:id="#+id/action_moreapps" android:icon="#drawable/ic_shop_black_24dp"
android:title="#string/action_more_apps"
android:orderInCategory="103" app:showAsAction="never"/>
<item android:id="#+id/action_exit" android:icon="#drawable/ic_close_black_24dp"
android:title="#string/action_exit"
android:orderInCategory="107" app:showAsAction="never"/>
</menu>
</item>
Hi I wouldike to know when I click on my bottomnavigationView how to display my search toolbar ?
getMenuInflater().inflate(R.menu.toolbar_menu, menu);
return super.onCreateOptionsMenu(menu);
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
return true;
case R.id.navigation_loope:
toolbar_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:title="Search"
android:id="#+id/action_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
Bottom_nav_view.xml
<item
android:id="#+id/navigation_home"
android:icon="#drawable/ic_home"
android:title="#string/title_home" />
<item
android:id="#+id/navigation_loope"
android:icon="#drawable/ic_loope"
android:title="#string/title_loope"
/>
<item
android:id="#+id/navigation_take_photo"
android:icon="#drawable/ic_take_photo"
android:title="#string/title_take_photo" />
<item
android:id="#+id/navigation_public"
android:icon="#drawable/ic_public"
android:title="#string/title_public" />
</menu>
I can't actually use getMenuInflater().inflate(R.menu.toolbar_menu, menu) I don't know how to implement it for doing the same result when i click on my loope (R.id.navigation_loope)
EDIT : Bottom_nav_view it's for my bottom bar and toolbar_menu for my topbar. If I click on the item navigation_loop, I wouldike to show the search bar on the top.
I am trying to display action overflow menu with icons in my one application. I am not getting icons in menu. My Target SDK = 23 and Minimum SDK = 16.
My Menu.xml is like below
<?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">
<!-- Single menu item
Set id, icon and Title for each menu item
-->
<item android:id="#+id/menu_donate"
android:icon="#drawable/new_facebook_page"
android:title="#string/facebook"
app:showAsAction="never" />
<item android:id="#+id/menu_settings"
android:icon="#drawable/new_facebook_page"
android:title="#string/facebook"
app:showAsAction="never" />
<item android:id="#+id/menu_logout"
android:icon="#drawable/new_facebook_page"
android:title="#string/facebook"
app:showAsAction="never" />
</menu>
and Java code is like below
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
But it does not showing icons in menu. Let me know if anyone can help me to achieve this without changing menu structure.
Thanks
Add below line to your java class inside onCreateOptionsMenu(Menu menu):
menu.add(0, 1, 1, menuIconWithText(getResources().getDrawable(R.mipmap.user_2), getResources().getString(R.string.action_profile)));
Try with below code :
#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_patient_home_screen, menu);
menu.add(0, 1, 1, menuIconWithText(getResources().getDrawable(R.mipmap.user_2), getResources().getString(R.string.action_profile)));
menu.add(0, 2, 2, menuIconWithText(getResources().getDrawable(R.mipmap.add_user), getResources().getString(R.string.action_add_user)));
menu.add(0, 3, 3, menuIconWithText(getResources().getDrawable(R.mipmap.switch_profile), getResources().getString(R.string.action_switch_profile)));
menu.add(0, 4, 4, menuIconWithText(getResources().getDrawable(R.mipmap.logout), getResources().getString(R.string.action_sign_out)));
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (item.getItemId()) {
case 1:
Toast.makeText(PatientHomeScreen.this, "Profile is Clicked", Toast.LENGTH_SHORT).show();
return true;
case 2:
Toast.makeText(PatientHomeScreen.this, "Add New User is Clicked", Toast.LENGTH_SHORT).show();
return true;
case 3:
Toast.makeText(PatientHomeScreen.this, "Switch Profile is Clicked", Toast.LENGTH_SHORT).show();
return true;
case 4:
Toast.makeText(PatientHomeScreen.this, "Sign Out is Clicked", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
private CharSequence menuIconWithText(Drawable r, String title) {
r.setBounds(0, 0, r.getIntrinsicWidth(), r.getIntrinsicHeight());
SpannableString sb = new SpannableString(" " + title);
ImageSpan imageSpan = new ImageSpan(r, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
Or, you can show icon with menu item by :
xml code :
<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"
tools:context=".MainActivity">
<item
android:id="#+id/action_alarm"
android:icon="#drawable/ic_accept"
android:orderInCategory="100"
android:title="#string/menu_create_alarm"
android:showAsAction="always|withText"
app:showAsAction="always|withText" />
Java Code :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(this).inflate(R.menu.menu_item, menu);
super.onCreateOptionsMenu(menu, inflater);
}
You can use the custom layout for menu item child
<?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">
<!-- Single menu item
Set id, icon and Title for each menu item
-->
<item android:id="#+id/menu_donate"
android:title="#string/facebook"
android:actionLayout="#layout/menu_donate_layout"
app:showAsAction="never" />
<item android:id="#+id/menu_settings"
android:title="#string/facebook"
android:actionLayout="#layout/menu_setting_layout"
app:showAsAction="never" />
<item android:id="#+id/menu_logout"
android:title="#string/facebook"
android:actionLayout="#layout/menu_logut_layout"
app:showAsAction="never" />
</menu>
Create menu_donate_layout
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/profile_icon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile" />
</LinearLayout>
Same create the separate layout of each menu item or change text and icon dynamically.
I click an Icon on the action bar to display a popup menu, then I click a popup menu item and a toast message in my Java code shows that it changes state from false to true. The problem is that when the popup menu is opened again no items are clicked. And clicking a popup menu item always shows that it changes state from false to true.
Does anyone have a code solution for this problem?
Thank you for your help.
Java code:
#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_action, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_popup) {
View menuItemView = findViewById(R.id.action_popup);
PopupMenu popupMenu = new PopupMenu(this, menuItemView);
MenuInflater inflater = popupMenu.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
int id = item.getItemId();
if (id == R.id.opt1_name) {
if (item.isChecked()){
item.setChecked(false);
Toast.makeText(getApplicationContext(), "Logic Set False= " + item, Toast.LENGTH_SHORT).show();
}
else{
item.setChecked(true);
Toast.makeText(getApplicationContext(), "Logic Set True= " + item, Toast.LENGTH_SHORT).show();
}
}
else if (id == R.id.opt2_date) {
if (item.isChecked()){item.setChecked(false);
Toast.makeText(getApplicationContext(), "Logic Set False= " + item, Toast.LENGTH_SHORT).show();
}
else{item.setChecked(true);
Toast.makeText(getApplicationContext(), "Logic Set True= " + item, Toast.LENGTH_SHORT).show();
}
}
return true;
}
});
popupMenu.show();
}
return super.onOptionsItemSelected(item);
}
menu_action.xml
<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" tools:context=".PlayerActivity">
<item android:id="#+id/action_popup" android:title="Sort Popup" android:icon="#drawable/ic_sort"
android:showAsAction="always" />
<item android:id="#+id/action_settings" android:title="Settings"
app:showAsAction="never" />
<item android:id="#+id/action_help" android:title="Help"
app:showAsAction="never" />
</menu>
popup_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/opt1_name"
android:title="Name" />
<item
android:id="#+id/opt2_date"
android:title="Date" />
</group>
</menu>
Check the error if you examine then you must have one listview in your mainlist.xml file with id as #android:id/list
<ListView
android:id="#android:id/list"
android:layout_height="wrap_content"
android:layout_height="fill_parent"/>
I am trying to have a search action on my action bar. I have set an icon and have showAsAction set to always but it is still always displayed in the overflow menu. How can I make it display on the action bar itself? Thanks!
Activity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
setTitle("Add");
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Toast.makeText(getApplicationContext(), "Settings",
Toast.LENGTH_LONG).show();
return true;
}
if (id == R.id.action_search) {
Toast.makeText(getApplicationContext(), "Search",
Toast.LENGTH_LONG).show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Menu XML file
<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"
tools:context="com.example.testtabs.MainActivity" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never"/>
<item
android:id="#+id/action_search"
android:actionViewClass="android.support.v7.widget.SearchView"
android:icon="#drawable/ic_search"
android:showAsAction="always"
android:title="#string/title_search"/>
</menu>
Either remove
android:actionViewClass="android.support.v7.widget.SearchView"
or delete your case statement for action_search in onOptionsItemSelected. Doing either of those will display the icon.
If you want to use SearchView the callback is handled differently than onOptionsItemSelected.
Documentation here: http://developer.android.com/guide/topics/ui/actionbar.html#ActionView
Just change app:showAsAction instead of android:showAsAction
<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"
tools:context="com.example.testtabs.MainActivity" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"`enter code here`
android:title="#string/action_settings"
app:showAsAction="never"/>
<item
android:id="#+id/action_search"
android:actionViewClass="android.support.v7.widget.SearchView"
android:icon="#drawable/ic_search"
app:showAsAction="always"
android:title="#string/title_search"/>
</menu>