Android ToolBar Menu Item not Clickable - android

My android app menu item is not clickable I Add app:showAsAction="always" and android:enabled="true" to the menu item and The Item Button is shown but it's not clickable, What Im missing here ?
App Theme : parent="Theme.MaterialComponents.DayNight.DarkActionBar"
Layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
android:orientation="vertical"
tools:context=".Settings.ReportTable">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:id="#+id/toolbar"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/balance_table_SV"/>
</LinearLayout>
Activity :
public class ReportTable extends AppCompatActivity {
ScrollView balance_table_SV;
TableLayout tableLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_table);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.excel);
balance_table_SV = findViewById(R.id.balance_table_SV);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.excel, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.menu.excel) {
export_to_excel();
}
return super.onOptionsItemSelected(item);
}
}

First of all, it looks like you're comparing the item ID to the resource ID of the entire menu (R.menu.excel). You should have an ID for each menu item to use for click handling:
<item android:id="#+id/excel" />
if(item.getItemId() == R.id.excel) { ... }
Secondly there seems to be quite a bit of confusion here between the Toolbar and the Android action bar. You are you using a mixture of both in the code you have provided which is causing the inconsistency.
Firstly, if you're using a Toolbar in your layout, you don't need the action bar at all, therefore you should be inheriting from a NoActionBar Material Components theme (such as Theme.MaterialComponents.DayNight.NoActionBar). Then in order to setup your Toolbar you have two options:
Set the Toolbar as the action bar
With this approach you can register the Toolbar to act as the action bar for an activity, which means it correctly triggers the onOptionsItemSelected callback etc. So to do this we need to register it in onCreate:
setSupportActionBar(toolbar);
Then you should probably be using onCreateOptionsMenu to inflate the menu instead of Toolbar.inflateMenu just as you've already done in your code:
getMenuInflater().inflate(R.menu.excel, menu);
And finally to listen for menu item clicks, you can override onOptionsItemSelected and check the item ID as I outlined above.
Setup the Toolbar independently
Instead of registering the Toolbar as the action bar, you can instead just use the Toolbar like any regular view and set it up directly. Firstly to inflate the menu you can call:
toolbar.inflateMenu(R.menu.excel);
Then in order to listen for click events you can attach an OnMenuItemClickListener as follows:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
...
}
});
Both approaches are valid but I personally prefer the second. It seems strange to try and work around the activity lifecycle when you could just treat the Toolbar normally.

Related

How to use NavigationView

I have an activity which has a navigationView and a toolbar (I set toolbar name manually).
My problem is; when I open the navigationView, it goes out of activity and back to previous activity.
I tried many ways to find the problem and I found when i wasn't using this line the problem has been solved and navigation menu opens without any problem.
setSupportActionBar(toolbar);
I don't know which one the problem is? toolbar or navigation?
Note : There is nothing special about the styles.
Activity :
Toolbar toolbar = findViewById (R.id.toolbar_StudentList);
setSupportActionBar(toolbar);//Set actionBar with toolbar
if(getSupportActionBar() != null)
{
getSupportActionBar().setDisplayShowTitleEnabled(false);//Remove actionBar title
toolbar.setTitle(mClassEntry.getClassName());
}
DrawerLayout drawer = findViewById (R.id.drawerLayout_StudentList);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this , drawer , toolbar , 0b0, 0);
toggle.syncState();
NavigationView drawerItems = findViewById (R.id.navigationView_StudentList);
drawerItems.setNavigationItemSelectedListener(item -> {
.
.
.
}
Xml :
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.user.classmanager.StudentActivity"
android:id="#+id/drawerLayout_StudentList"
style="#style/DrawerLayout_all"
>
<FrameLayout
android:id="#+id/frameLayout_StudentList"
style="#style/Width_height_all_both_matchParent"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_StudentList"
style="#style/ToolBar_all"
/>
<RelativeLayout
style="#style/RelativeLayout_searchView_all"
>
<android.support.v7.widget.SearchView
android:id="#+id/searchView_StudentList"
style="#style/SearchView_all"
/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_StudentList"
style="#style/RecyclerView_FrameLayout_all"
/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigationView_StudentList"
style="#style/NavigationView_StudentList"
/>
</android.support.v4.widget.DrawerLayout>
Also my toolbar has a icon to close activity :
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toolbar_backicon, menu);//Back item in Toolbar
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item)
{
finish();//close activity
return super.onOptionsItemSelected(item);
}
in
public boolean onOptionsItemSelected(MenuItem item)
{
finish();//close activity
return super.onOptionsItemSelected(item);
}
you must specify the id of your close button so that the activity only closes when you click on the icon on the close button . In this you activity will close everytime , so must replace the code to something like this
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getId()==R.id.closeButton)
{ finish();//close activity
return true;
}
return super.onOptionsItemSelected(item);
}

Android ActionBar Overlap with Settings Options

As you can see from the image below my Action Bar Menu Items overlap my custom ActionBar. This is because I use the theme .NoActionBar and then in .java declare my own action bar as follows:
public class MenuActivity extends ActionBarActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_activity);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
The toolbar:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/ColorPrimary"
android:elevation="4dp">
and the layout...
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
android:id="#+id/tool_bar"
layout="#layout/custom_toolbar"
></include>
<TextView
android:layout_below="#+id/tool_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
So as you can see the problem arises from having a .NoActionBar theme. I have tried looking around and adding a padding to the top of my Menu items however it doesn't work. Any help appreciated.
This is totally expected behaviour and follows the Material Design official guidelines.
Menus appear above all other in-app UI elements.
It is brought to you by either a Theme.Material theme (if you are on API > 21) or an Theme.AppCompat if you are using support-v7 as it looks. You shouldn't worry about that.
If this is not what you are expecting from your app, try switching to older themes, like Holo stuff. From a design point of view this is not really recommended.

Custom icon in Android toolbar

I'm trying to use define a custom icon in the support Toolbar but the only icon shown is a left arrow... I tried to set it in the layout and programmatically but the result is the same.
Here is my Activity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
toolbar.setNavigationIcon(R.drawable.ic_launcher);
toolbar.setTitle("");
setSupportActionBar(toolbar);
}
And my toolbar layout
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/my_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:navigationIcon="#drawable/ic_action_bar"
android:minHeight="#dimen/action_bar_size"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
/>
Just tried it myself and the issue seems to be that you have to call setNavigationIcon after setSupportActionBar(toolbar). Otherwise it'll only show the arrow as you've described.
So to fix this issue just change the code like this:
//...
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_launcher);
toolbar.setTitle("");
Note: Same goes for setting the title, contentDescription etc. I don't know if this a bug or if it is intended, but it's definitely kinda strange.
In case you want to change menu icon. (maybe somebody will need it)
In your activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_info, menu);
return true;
}
in your menu folder in res. (menu_info.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/menu_info_action"
android:icon="#drawable/ic_info_icon"
android:title="#string/information"
app:showAsAction="ifRoom"/>
</menu>
The current most efficient way to achieve this:
first display the left hand side icon correctly, call this function in onCreateView or onCreate:
protected void enableDisplayHomeAsHome(boolean active) {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(active); // switch on the left hand icon
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_home); // replace with your custom icon
}
}
Now you can intercept this button press in your activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: { //index returned when home button pressed
homeButtonPressed();
return true;
}
}
return super.onOptionsItemSelected(item);
}
ActionBar.setHomeAsUpIndicator(...);
This one works for me.

Action bar and menus not shown in AccountAuthenticatorActivity

Since I use an action bar instead of menus for my application, no action bar nor/ menus are shown in my implementation of AccountAuthenticatorActivity. Other activities show action bar without problem.
I'm not sure if it's a bug or a missing adaptation of the code on my side. Has someone experienced the same problem? I didn't find any other question related to this problem.
public class MyAuthenticatorActivity extends AccountAuthenticatorActivity {
...
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
XML menu that should be right as it is used in many other activities:
<?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/ic_menu_home"
android:orderInCategory="110"
android:showAsAction="ifRoom"
android:title="#string/menu_home"/>
<item
android:id="#+id/menuSettings"
android:icon="#drawable/ic_menu_settings"
android:orderInCategory="111"
android:showAsAction="ifRoom"
android:title="#string/menu_settings"/>
<item
android:id="#+id/menuInfo"
android:icon="#drawable/ic_menu_info"
android:orderInCategory="113"
android:showAsAction="ifRoom"
android:title="#string/menu_info"/>
</menu>
I know my answer is late. But I was able to get around this base on this one. It seems the AccountAuthenticatorActivity doesn't really have an ActionBar for some reason. Esp. it is really hard to work on when you want to use the support-library.
Here is how I did it:
You have to enclose your activity layout using a CoordinatorLayout:
<android.support.design.widget.CoordinatorLayout
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"
android:id="#+id/coordinatorlayout_homescreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_login"
tools:context="com....LoginActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingtoolbarlayout_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/actionBarSize"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="64dp"
app:expandedTitleMarginEnd="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
...
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
As you can see, I placed an AppBarLayout as per the docs and have the appcompat version of the Toolbar here. We will assign this Toolbar later.
If you prefer to make the CoordinatorLayout just like any ordinary activity without animated-coordinated scroll, you can just set the attribute of CollapsingToolbarLayout like the following:
android:minHeight="?android:attr/actionBarSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
This will make sure your Toolbar will not disappear/collapse when you scroll up as the minHeight has been set to ?android:attr/actionBarSize. You can checkout its behavior here.
Next on your LoginActivity which extends AccountAuthenticatorActivity, you have to use AppCompatDelegate but before that make sure you LoginActivity implements the AppCompatCallback:
public class LoginActivity extends AccountAuthenticatorActivity
implements AppCompatCallback
{
...
private AppCompatDelegate mAppCompatDelegate;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
...
mAppCompatDelegate = AppCompatDelegate.create(this, this);
mAppCompatDelegate.setSupportActionBar(mToolbarLogin);
ActionBar actionBar = mAppCompatDelegate.getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(getString(R.string.activity_login));
mCollapsingToolbarLayoutLogin.setTitleEnabled(false);
}
There are three methods you have to implement, but on my research they seem to do nothing fancy esp if you only want to show an ActionBar, so on this use-case you can leave them blank:
#Override
public void onSupportActionModeStarted(ActionMode mode)
{
}
#Override
public void onSupportActionModeFinished(ActionMode mode)
{
}
#Nullable
#Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback)
{
return null;
}
The line mAppCompatDelegate = AppCompatDelegate.create(this, this); ask for the Activity instance on the first param, the second param is asking for the callback.
Also, another thing. If you want the back button to be present as shown on this code, it doesn't respond to click. You may have to override it:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case android.R.id.home:
onBackPressed();
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
One small quirk I found going using this is that the status bar appeared white on some devices. I am still looking how to fix it but at least the AccountAuthenticatorActivity now has an ActionBar. I don't like this solution as it is a little bit hacky to may taste. So much hassle to implement a seemingly basic behavior for Activity.
HTH

onCreateOptionsMenu is never called

I am having some trouble getting an options menu working in Android. I have built apps before, and they all worked fine, but now the menu just doesn't pop up.
The code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_video, menu);
return true;
}
the whole method is never even called (checked by setting a breakpoint). The activity is super-simple, it just has a VideoView in it, with an OnTouchListener set.
I am using Android 4.0.4 on a Samsung Galaxy 10.1, API level 15, minSDK 15. Am I missing something?
In the latest versions of Android when using the compat library for toolbar, is very common that this happens, in order to get the menu items to display in the toolbar you must do the following:
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Call setHasOptionsMenu function from onCreate first. The onCreateOptionsMenu will be automatically called.
Try this:
setHasOptionsMenu(true)
If the phone you test on has a menu button onCreateOptionsMenu wont't be called on start with the theme:
android:theme="#android:style/Theme.Black.NoTitleBar"
But when you click the menu button the onCreateOptionsMenu will be called. I don't know what happens on phones without hardware buttons...
In the method: Fragment#onCreateView(...) you should put:
setHasOptionsMenu(true);
Then your method will be called.
That is because the activity does not have the toolbar.
There are 2 steps in order to do it.
First, you need to add the toolbar in your activity.xml which is in res/layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"">
<!-- add this part-->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Second, let your activity append it
in JAVA
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
or in Kotlin
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
I was having the same problem (menu not showing up, onCreateOptionsMenu not being called).
If you are calling this within a fragment, you need to override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) not public boolean onCreateOptionsMenu(Menu menu). Fragments do not use the latter, so they will never even call it.
Activity menu
Fragment menu
This happens because you have defined a Theme in your styles.xml that has something like:
<style name="AppTheme" parent="Theme.AppCompat.Light.**NoActionBar**">
You can manually create a toolbar, and then yo have to add it to your Activity.
The xml for the toolbar view could be something like:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</androidx.appcompat.widget.Toolbar>
Then, in the Activity, you have to "display" it :
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
}
And now, you can create the menu with the known onCreateOptionsMenu
I had the same issue. My problem was solved by inheritance of a different activity class.
So I had been doing:
public class WelcomeActivity extends Activity
but changed this to:
public class WelcomeActivity extends AppCompatActivity
This way I was saying that say an action bar can be added to your activity.
Maybe you also have overrode onKeyDown method and made it always return true. Returning true means that keyEvent will be prevented from being propagated further. See code below:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
/*
handling event
*/
return true; //onCreateOptionsMenu won't be invoked.
}
I had a similar issue, but a different solution I am sharing with the community (as it took me one hour to understand what was happening):
abstract class BaseActivity : AppCompatActivity{
override fun onCreate(savedInstanceState: Bundle?) {
setSupportActionBar(my_toolbar)
}
}
class MyActivity : BaseActivity{
// TODO : some good stuff
}
where my_toolbar is an object created in my xml file through dataBinding.
The issue looks the same, no toolbar appear, no call to onCreateOptionsMenu.
My solution was to promote this code to the child class and not to that basic, as my_toolbar is only initialized as the child class is built.
If above answer doesn't work, make sure that you are using the same id of toolbar.
layout_app_bar.xml
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
activiy_main.xml
<include
android:id="#+id/app_bar"
layout="#layout/layout_app_bar" />
in java file:
don't call:
Toolbar tb = findViewById(R.id.toolbar);
please call:
Toolbar tb = findViewById(R.id.app_bar);
Try This It works for me:---
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.home_page_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
Toast.makeText(this, "You pressed the Delete!",
Toast.LENGTH_LONG).show();
break;
case R.id.menu_setting:
Intent intent=new Intent(HomePage.this,Setting.class);
startActivity(intent);
finish();
Toast.makeText(this, "You pressed the Setting!",
Toast.LENGTH_LONG).show(); break;
}
return super.onOptionsItemSelected(item);
}

Categories

Resources