How "onOptionsItemSelected" works for Fragments? - android

Menu Items getting disappeared in my app.
Initially i created menu items as follow. but menu getting disappeared in some android versions.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHelper tabHelper = getTabHelper();
CompatTab menuTab = tabHelper.newTab("menu").setText(
R.string.tab_section1).setIcon(R.drawable.home_icon).setTabListener(
new InstantiatingTabListener(this, MenuFragment.class));
tabHelper.addTab(menuTab);
CompatTab favTab = tabHelper.newTab("favourites").setText(
R.string.tab_section2).setIcon(R.drawable.favourites_icon).setTabListener(
new InstantiatingTabListener(this, FavouritesFragment.class));
tabHelper.addTab(favTab);
}
THIS ABOVE CODE WORKS FINE IN LATEST ANDROID 4.1.3 BUT FAILS TO DISPLAY IN 4.0.1 and 4.0.3
SEEMS TO BE SOME LAYOUT ISSUE.
TO RESOLVE i added menu xml as follow
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menuhome"
android:icon="#drawable/map_icon"
android:title="#string/tab_section1"
android:orderInCategory="1"
android:showAsAction="always|withText" />
<item android:id="#+id/menumap"
android:icon="#drawable/map_icon"
android:title="#string/tab_section2"
android:orderInCategory="2"
android:showAsAction="always|withText" />
and added onOptionItemSelected as follow
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.menuhome:
finish();
return true;
case R.id.menumap:
//ERROR
//HOW CAN I CALL FRAGMENT HERE.?
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}

Related

setOnMenuItemClickListener not working for Bottom App Bar when using app:actionLayout

I have used bottom app bar and the problem is when i used a custom layout for my menus using app:actionLayout in menu, the click is not working for these menus i.e setOnMenuItemClickListener for bottomappbar not working.?
It is working fine when actionLayout not used.
BottomAppBar bottomAppBar;
bottomAppBar = findViewById(R.id.bar);
bottomAppBar.replaceMenu(R.menu.announcement_menu);
bottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_all:
Log.d("Announcement", "All clicked");
break;
case R.id.action_rec:
Log.d("Announcement", "Received clicked");
break;
case R.id.action_sen:
Log.d("Announcement", "Sent clicked");
break;
}
return false;
}
});
And the menu 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/action_all"
app:actionLayout="#layout/custom_menu_row_all"
android:title="All"
app:showAsAction="always" />
<item
android:id="#+id/action_rec"
app:actionLayout="#layout/custom_menu_row_received"
android:title="Received"
app:showAsAction="always" />
<item
android:id="#+id/action_sen"
app:actionLayout="#layout/custom_menu_row_sent"
android:title="Sent"
app:showAsAction="always" />
</menu>
Got working with following:
View v = bottomAppBar.getMenu().findItem(R.id.action_rec).getActionView().findViewById(R.id.tvTitle);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Announcement", "Received clicked");
}
});

Add right margin to the options menu sub-items

Currently, my options menu is aligned to the end of the screen. I want to give it a margin, something like android:layout_marginEnd = "20dp". How can I achieve this?
My options 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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/menu_items"
android:icon="#drawable/menu_icon"
app:showAsAction="always">
<menu>
<group android:id="#+id/item1">
<item
android:id="#+id/download"
android:icon="#drawable/download_icon"
android:title="Download"></item>
</group>
<group android:id="#+id/item2">
<item
android:id="#+id/invite"
android:icon="#drawable/invite_icon"
android:title="Invite"></item>
</group>
</menu>
</item>
</menu>
My Custom Toolbar:
<androidx.appcompat.widget.Toolbar
android:id="#+id/menu_toolbar"
app:popupTheme="#style/ThemeOverlay.MyTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_below="#id/greetText"> <!--assume it comes somewhere in the centre due to this-->
</androidx.appcompat.widget.Toolbar>
My Theme for menu items:
<style name="ThemeOverlay.MyTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#color/dimGray</item>
<item name="android:textSize">14sp</item>
<item name="android:layout_marginEnd">20dp</item> <!-- doesn't work-->
<item name="android:fontFamily">#font/quicksand_medium</item>
<item name="android:background">#drawable/options_menu_background</item>
</style>
Here is the image of my problem. It shows how the end of the menu and the screen are aligned. I want space/margin between these two.
This is an interesting problem. I tried with many things found on the internet, but nothing works. I tried setting the actionOverflowMenuStyle with dropDownHorizontalOffset attribute which does not work either. Finally, I ended up getting a PopupMenu which works just fine. Here is the implementation.
Get your initial menu shorter with a single item which will open up the popup menu as a submenu.
<?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/menu_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Then create another menu, in your /res/menu/ folder, named popup_menu.xml like the following.
<?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/menu_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Now in your MainActivity, just add the following functions to handle the click action of the menu button and the popup menu.
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = findViewById(R.id.menu_toolbar);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_items:
showPopupMenu();
return true;
default:
return false;
}
}
public void showPopupMenu() {
PopupMenu popup = new PopupMenu(this, findViewById(R.id.menu_items));
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.popup_menu);
popup.setGravity(Gravity.END);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popup);
argTypes = new Class[]{boolean.class};
menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true);
} catch (Exception e) {
e.printStackTrace();
}
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.invite:
Toast.makeText(this, "Invite", Toast.LENGTH_LONG).show();
return true;
case R.id.download:
Toast.makeText(this, "Download", Toast.LENGTH_LONG).show();
return true;
default:
return false;
}
}
}
I put the working code in this Github Branch. You might consider cloning from that branch and run the application to check if that suffices your expectation.
Hope that helps!

Not able to get navigation drawer item id to open an activity

I am trying to get my app to work to open my activity to click on the navigation drawer but I am not able to get the menu id.
.java
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.home_id:
Toast.makeText(MainActivity.this, "tarun", Toast.LENGTH_SHORT).show();
Intent home_Intent = new Intent(MainActivity.this,MainActivity.class);
startActivity(home_Intent);
break;
return true;
}
});
This is my menu item xml here is also provide the id and the name which will show me in navigation view
<?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/home_id"
android:title="Home"
android:icon="#drawable/home"/>
</group>
</menu>

Android ActionBar not showing icons

I have seen this question asked many times, however, none of those solutions have helped me. My problem is that I have an ActionBar menu and I want its items to always be displayed on the ActionBar instead of the drop down menu.
I have tried actions suchs as "ifRoom", "always", etc. and they still show only with text on the drop down menu.
Menu: devotional_fragment_actions.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_previous"
android:icon="#drawable/ic_action_previous_item"
android:title="#string/previous_action"
app:showAsAction="always"/>
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_go_to_today"
android:title="#string/date_action"
app:showAsAction="always"/>
<item android:id="#+id/action_next"
android:icon="#drawable/ic_action_next_item"
android:title="#string/next_action"
app:showAsAction="always"/>
</menu>
On my fragment I have:
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// action bar
inflater.inflate(R.menu.devotional_fragment_actions, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection of action bar
switch (item.getItemId()) {
case R.id.action_search:
showDatePickerDialog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The menu works fine but is not displaying as I want it. Thanks
In each item use android namespace instead of app. You can even remove this namespace declaration xmlns:app="http://schemas.android.com/apk/res-auto".
Try set it like in code below:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/action_previous"
android:icon="#drawable/ic_action_previous_item"
android:title="#string/previous_action"
android:showAsAction="always"/>
</menu>

Fourth level menu option not working

I am using a fourth level Active Menu on my app, everything works perfect but when I select one item on the Menu fourth level, the system is not calling onOptionsItemSelected anymore, so I can't get the selected item on my app.
Here is my code
EDIT 1: the dash - in the Id's are making confusion, I am removing them from the code. Sorry for that
public class Main extends FragmentActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// .... some code
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.Level1: {
Toast.makeText(getBaseContext(), "Level 1", Toast.LENGTH_SHORT).show();
break;
}
case R.id.Level2: {
Toast.makeText(getBaseContext(), "Level 2", Toast.LENGTH_SHORT).show();
break;
}
case R.id.Level3: {
Toast.makeText(getBaseContext(), "Level 3", Toast.LENGTH_SHORT).show();
break;
}
case R.id.Level4: {
Toast.makeText(getBaseContext(), "Level 4", Toast.LENGTH_SHORT).show();
break;
}}
return true;
}
and here the XML file main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/Level1"
android:showAsAction="ifRoom"
android:title="#string/Level1">
<menu>
<item android:id="#+id/Level2"
android:title="#string/Level2">
<menu>
<item android:id="#+id/Level3"
android:title="#string/Level3">
<menu>
<item android:id="#+id/Level4"
android:title="#string/Level4"/>
</menu>
</item>
</menu>
</item>
</menu>
</item>
</menu>
I was reading the documentation but it doesn't states a limit for nested sub-menus.
Finally my solution was to append a android:onClick="onOptionsItemSelected" to the fourth level item like:
<menu>
<item android:id="#+id/Level4"
android:onClick="onOptionsItemSelected"
android:title="#string/Level4"/>
</menu>
to force the call to onOptionItemSelected, it works but is there a better solution???
EDIT 2: I just found that this walk-around doesn't works with Android version 4.0.3 or earlier.!!! not even using onMenuItemSelected...!!!
Now I am in problem, please help...!!

Categories

Resources