Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Conversation

@DayS
Copy link
Contributor

@DayS DayS commented Apr 22, 2013

Referred to #560 and #549

This PR add a @OptionMenuItem which allows the developer to inject a MenuItem (android or ActionBarSherlock) into an activity.

The developer should just be aware that injection is done in onCreateOptionsMenu() so the fields will be set only when the menu is displayed (immediately if an ActionBar is provided, otherwise when the user press the Menu button)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if extended SherlockActivity contains android MenuItem or vice versa? I haven't tried, but it seems that the user will get an error in generated folder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you're right. We need to add a check on the super class.

@naixx
Copy link
Contributor

naixx commented Apr 22, 2013

👍 Great feature!

JoanZapata added a commit that referenced this pull request May 21, 2013
Add a @OptionMenuItem annotation to inject MenuItem
@JoanZapata JoanZapata merged commit c55bbe5 into develop May 21, 2013
@JoanZapata JoanZapata deleted the 560_MenuItem branch May 21, 2013 19:30
@DayS
Copy link
Contributor Author

DayS commented Jun 20, 2013

Wiki updated

@tpettersen
Copy link

Perhaps the wiki should state that when injecting an OptionsMenuItem you cannot use the injected variable in methods annotated with @AfterInject.

The life cycle of Android is onCreate() --> OnStart() --> OnResume --> OnCreateOptionsMenu(), whereas @AfterInject runs in onCreate() and @OptionsMenuItem runs in OnCreateOptionsMenu().

Unless im completely lost here?

@DayS
Copy link
Contributor Author

DayS commented Sep 1, 2013

Nop, you're right :)

More precisely, onCreateOptionsMenu will be called the first time menu is displayed, as explained on Android javadoc.
The post of CommonsWare on StackOverflow also show us that on Android >= 3.0, the onCreate method is called first, and before it finishes onCreateOptionsMenu is called, because of the action bar.

However, menu items still not useable in @AfterInject nor @AfterViews annotated methods. I'll update the wiki.

@DayS
Copy link
Contributor Author

DayS commented Sep 1, 2013

Wiki updated

@athkalia
Copy link

So just to get this right, if I need to disable a button when I first initialize it (an action that I would usually do inside onCreateOptionsMenu) where can I do that if I want to use the annotation?

@athkalia
Copy link

Funny when you are searching the answer of something, only to realize that you are the one that asked the same question 11 months ago ! I am guessing that one cannot do that with androidannotations.

@WonderCsabo
Copy link
Member

@athkalia as @DayS explained it back then, the item is only injected at onCreateOptionsMenu. So cannot access the item in @AfterInject, but you can in your onCreateOptionsMenu method (or anywhere after onCreateOptionsMenu is done).

@MarcosEich
Copy link

Thanks for the explanation guys, I had some trouble with it.

@TomIsYourName
Copy link

So there is still no solution for this question ? Which means we can not use annotation with menu options ?

@WonderCsabo
Copy link
Member

WonderCsabo commented May 26, 2016

@TomIsYourName what is your problem exactly?

@laszlourszuly
Copy link

If I'm guessing your question correctly, @TomIsYourName, I would say "no, you can't". Not the way I think you mean at least.

Your menu items aren't available in @AfterInject or @AfterViews since they are inflated by Android (and thereby also injected by AndroidAnnotations) well after those two states.

I would suggest you calculate your desired menu item state in either @AfterInject or @AfterViews and store it in a member field. When the menu then, at some point in the future, is inflated and injected in your activity, you already have your state prepared and can apply it to the menu item of your choice then.

The below code shows an example where you fetch a couple of items from the network and based on whether that result is empty or not, you set your menu item in question to either enabled or disabled:

A different, maybe more down-to-earth example that would describe the same situation could be if you want to give your grand child a T-shirt. You can't dress him in it now, because he's not born yet. You can still buy the T-shirt now and put it in your wardrobe, but you have to await his birth before you can give it to him.

public class MyActivity extends AppCompatActivity {

    @Bean
    protected MyNetworkClient myNetworkClient;

    private MenuItem myMenuItem = null;
    private boolean shouldBeEnabled = false;

    @AfterInject
    protected void afterInject() {
        myNetworkClient.getProductNames(new SuccessListener() {
            public void onSuccess(List<String> productNames) {
                shouldBeEnabled = !productNames.isEmpty();
                updateMyMenuItem();
            }
        });
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        myMenuItem = menu.findItem(R.id.action_continue);
        updateMyMenuItem();
    }

    private void updateMyMenuItem() {
        if (myMenuItem != null) {
            myMenuItem.setEnabled(shouldBeEnabled);
        }
    }

}

If you strictly want to, you could maybe even replace the onCreateOptionsMenu(...) method with a corresponding @InjectMenu annotated method, but this requires AndroidAnnotations 4.0.0 or later:

@InjectMenu
protected void injectMenu(Menu menu) {
    myMenuItem = menu.findItem(R.id.action_continue);
    updateMyMenuItem();
}

@dodgex
Copy link
Member

dodgex commented Jun 1, 2016

you can use @OptionsMenuItem on a method too.

@OptionsMenuItem(R.id.action_continue)
void singleInjection(MenuItem item) {
    // do stuff with `item`
}

this method will be called once your menu has been inflated.

@Rafasystec
Copy link

Rafasystec commented Jun 22, 2020

you can use @OptionsMenuItem on a method too.

@OptionsMenuItem(R.id.action_continue)
void singleInjection(MenuItem item) {
    // do stuff with `item`
}

this method will be called once your menu has been inflated.

It worked for me. Thank you. @dodgex

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.