Armando Sudi
Armando Sudi

Reputation: 161

custom actionbar menu item not responding on one click

I have created a custom layout for a menu item. Now I need it to load a new activity when clicked. The code logic goes as follows:

Menu declaration in resources:

<item android:id="@+id/shoppingCart"
    android:title="cart"
    android:background="@layout/basket_notification_counter"
    android:icon="@drawable/ic_add_shopping_cart_white_24dp"
    app:showAsAction="always" />

The activity is composed of fragments under respective tabs. From what I've gathered here on SO, I need to call setHasOptionsMenu(true); inside the onCreateView method inside the fragment and I have done so.

Now inside the activity, the 2 main important methods, respectively onCreateOptionsMenu and onOptionsItemSelected, are as follow:

package project.activities;

//... Imports come here


public class SalesActivity extends ActionBarActivity
{
    private final static String TAG = "PROJECT";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sales);

        // Setup the action bar
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showActionBar();
            }
        });
    }

    /**
     * Creates menus found the action bar
     *
     * @param menu the menu to work on
     * @return true
     */

    @Override
    public boolean onCreateOptionsMenu(final Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_sale, menu);

        final MenuItem item = menu.findItem(R.id.shopping_cart);
        // THIS IS THE PROBLEM
        // This workd but erratcally. After a number of clicks, it loads the activity specified in onOptionsItemSelected
        // This is random: sometimes one click, sometimes 2 or up to 7 clicks so far.
        item.getActionView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                menu.performIdentifierAction(item.getItemId(), 0);
            }
        });

        /**
         // Also tried this but didn't work. Didn't also throw an exception to tell something was wrong
        item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                LoggedInActivity.this.showCart();
                return true;
            }
        });
        */

        return true;
    }

    /**
     * Handles menus in lists
     *
     * @param item  the selected item
     * @return the selected item
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        int id = item.getItemId();
        switch (id) {
            case R.id.shopping_cart:
                Intent intent = new Intent(LoggedInActivity.this, CheckOutActivity.class);
                startActivity(intent);
                return true;
            case R.id.action_settings:
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    /**
     * When the screen is rotated, this method is called
     *
     * @param newConfig the new app configuration
     */
    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
    }

    /**
     * Recreates an item in cases where the app is pushed to the background
     *
     * @param savedInstanceState the bundle
     */
    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
    }

    /**
     * Handles the action bar
     */
    public void showActionBar()
    {
        // Initialize the action bar
        ActionBar actionBar = getSupportActionBar();
        //actionBar.setElevation(0);

        // Set up tabs
        showActionBarTabs(actionBar);
    }

    /**
     * Setup the actionbar tabs
     * @param actionBar the actionBar we get from the activity and style
     */
    public void showActionBarTabs(final ActionBar actionBar)
    {
        //... I set up the actionbar tabs here
    }
}

The problem is as follows: when clicking on the menu item in the actionbar, it works rather "randomly". Sometimes, it will work after one click, other times it loads the activity 4 clicks or 3 clicks. There is no consistency of 1 click. What seems to be the problem?

Upvotes: 4

Views: 3562

Answers (8)

Reypak_UG
Reypak_UG

Reputation: 21

Faced a similar problem. Action bar created but not responding to item clicks, particularly those set to showAsAction="always".

Eventually discovered the problem was being caused by invalidateOptionsMenu();
which i was calling inside the onCreateOptionsMenu(...) method.

I changed this and it fixed the issue.

Upvotes: 0

Kostya M
Kostya M

Reputation: 204

Please, try this in your

onCreateOptionsMenu(menu: Menu, inflater: MenuInflater)

method

Kotlin

inflater.inflate(R.menu.my_menu, menu)
menu.findItem(R.id.my_custom_item).actionView.setOnClickListener {
            println("КЛИК")
        }

Java

inflater.inflate(R.menu.my_menu, menu)
findItem(R.id.my_custom_item).getActionView().setOnClickListener(v -> System.out.println("click");

It worked for me

Upvotes: 2

devDeejay
devDeejay

Reputation: 6019

For whom the above solution might not be working,

Make sure your <Toolbar> is a child of <AppbarLayout> something like this:

<com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

    <androidx.appcompat.widget.Toolbar
            android:background="@drawable/white_grey_border_bottom"
            android:id="@+id/homeActivityToolbar"
            android:layout_width="match_parent"
            app:titleTextColor="@color/dark_grey"
            android:layout_height="50dp" app:layout_constraintTop_toTopOf="parent"/>

</com.google.android.material.appbar.AppBarLayout>

BTW, my project is using AndroidX so be careful if you are copy pasting this code.

Upvotes: 0

Because your activity's layout root GroupView can prevent click events from being dispatched to Toolbar menu items (if you are using a Toolbar for instance alongside with CoordinatorLayout), you should try to add

android:focusable="false"
android:clickable="false"

to your root GroupView

You also need to override onOptionsItemSelected as follow (Kotlin version):

override fun onOptionsItemSelected(item: MenuItem): Boolean {
        super.onOptionsItemSelected(item)
        when (item.itemId) {
            R.id.menu_favorite -> {
                handleFavorite(item)
            }
        }
        return true
    }

and don't forget to pass the MenuItem as parameter to your function, even if you're not using it:

private fun handleFavorite(item: MenuItem) {
        //TODO: Whatever you need
    }

Upvotes: 0

Luis Moreno
Luis Moreno

Reputation: 41

Instead of using android:actionLayout

Change the icon on the activity using this Method

public static Drawable convertLayoutToImage(Context mContext, int count, int drawableId) {
    LayoutInflater inflater = LayoutInflater.from(mContext);
    View view = inflater.inflate(R.layout.{your_custom_layout}, null);

    /*Edit other elements here*/

    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

    view.setDrawingCacheEnabled(true);
    view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
    view.setDrawingCacheEnabled(false);

    return new BitmapDrawable(mContext.getResources(), bitmap);
}

You must edit it to suit your configuration

To change the icon do this

menuItem.setIcon(Converter.convertLayoutToImage(localContext, 2, R.drawable.{your_drawable_resource}));

Upvotes: 0

Anatolii Shuba
Anatolii Shuba

Reputation: 6075

The problem is your custom menu item layout. Try to add custom click listener for the your menu

<item android:id="@+id/shoppingCart"
android:title="cart"
android:background="@layout/basket_notification_counter"
android:icon="@drawable/ic_add_shopping_cart_white_24dp"
app:showAsAction="always" 
android:onClick="shoppingCartClickListener"/>

and

public void shoppingCartClickListener(View v) {
    // Process click here
}

Hope that helps

Upvotes: 0

Deveesh
Deveesh

Reputation: 129

I had the same problem with my App. The action bar was being created but was not responding to the clicks. I previously had relative layout on that activity, I changed it to Linear Layout and adjusted the widget`s size and orientation to look like before. It solved the problem for me. Give it a try. Hope it helps :)

Upvotes: 0

Pacific P. Regmi
Pacific P. Regmi

Reputation: 1607

Look at your menu item clickable should be true or remove android:clickable="fales" and remove android:actionLayout="@layout/basket_notification_counter" , Your menu item Look like this.

<item android:id="@+id/shopping_cart"
    android:title="cart"
    android:icon="@drawable/ic_add_shopping_cart_white_24dp"
    android:clickable="true"
    app:showAsAction="always" />

OR

   <item android:id="@+id/shopping_cart"
        android:title="cart"
        android:icon="@drawable/ic_add_shopping_cart_white_24dp"
        app:showAsAction="always" />

Upvotes: 1

Related Questions