Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Actionbar items are duplicating

Tags:

I have Action Bar in my application. I am adding action items using menu.xml. I am using action bar-compat as my support library. I observed a weird issue where my action items are getting duplicated.

I am finding this issue randomly when leave my device idle or work with other applications. Please find the screen shot and my code below:

private LoginWebActivity mContext; private final String TAG = "LoginFragment";  // for metrics private String mPageNameSignIn = "signin";  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {     mView = inflater.inflate(R.layout.webview, container, false);      return mView; }  @Override public void onActivityCreated(Bundle savedInstanceState) {     super.onActivityCreated(savedInstanceState);     mContext = (LoginWebActivity) getActivity();     initFragment();  }  @Override public void onResume() {      super.onResume(); }  /**  * Initialises the views and variables of the fragment.  */ @SuppressLint({ "JavascriptInterface", "SetJavaScriptEnabled" }) protected void initFragment() {       mWebView = (WebView) mView.findViewById(R.id.webView);     Bundle b = mContext.getIntent().getExtras();     if (b != null) {         mUrl = b.getString(Constants.EXTRA_WEB_LOGIN_URL);     }     super.initFragment();      setHasOptionsMenu(true); }  @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {     inflater.inflate(R.menu.signin, menu);     super.onCreateOptionsMenu(menu, inflater); }  @Override public boolean onOptionsItemSelected(MenuItem item) {     // Navigate     switch (item.getItemId()) {     case R.id.menu_item_signup:         mContext.onSignUpClick();         break;     case android.R.id.home:         if (!goBack())             getActivity().finish();     default:         break;     }     return super.onOptionsItemSelected(item); } 

My XML :

<?xml version="1.0" encoding="utf-8"?> 

<item     android:id="@+id/menu_item_signup"     allergy:showAsAction="ifRoom"     android:title="@string/sign_up"> </item> 

enter image description here

like image 527
Ganesh Avatar asked Nov 05 '13 10:11

Ganesh


People also ask

How do we remove the default ActionBar of an application?

If you want to hide Action Bar from the entire application (from all Activities and fragments), then you can use this method. Just go to res -> values -> styles. xml and change the base application to “Theme. AppCompat.

What is an ActionBar?

An on-screen toolbar displaying icons that are clicked or tapped to perform various functions. For example, the menu bar at the top of an Android app is called an action bar.

Can single action bar can control multiple activities?

You can create class named BaseActivity which will extend AppCompatActivity and put there the code and functionality you want to use in every other Activity . Then in every of your activities, you will extend BaseActivity instead of AppCompatActivity .

How do I hide a menu item in the ActionBar?

You can set a flag/condition. Call invalidateOptionsMenu() when you want to hide the option. This will call onCreateOptionsMenu() .


2 Answers

You must clear your menu object before adding items. I had the same problem and this was the best solution that I've found.

@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {     menu.clear();     inflater.inflate(R.menu.signin, menu);     super.onCreateOptionsMenu(menu, inflater); } 
like image 183
Renan Bandeira Avatar answered Oct 13 '22 01:10

Renan Bandeira


Pretty late to this party, but for anyone that comes across this via the Google like I did, here's the real problem.

You didn't post your Activity code that's creating the Fragment, but I will venture to guess that it looks something like this:

    @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_layout);         Fragment fragment = ...         getSupportFragmentManager()             .beginTransaction()             .add(R.id.fragment_container, fragment)             .commit();     } 

The problem with this is that when the activity goes through its lifecycle (which would happen "when leave my device idle or work with other applications", as you say), the system will save and restore the state of fragments for you. But with this code, you also are adding a new fragment to your Activity, so you end up with multiple fragments running in your activity, each adding an item to the menu.

While the posted workaround will address the duplicate menu entries issue, it would leave these extra fragment instances lying around, which is obviously not what you want.

The correct fix is a simple null check:

    @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_layout);          if (savedInstanceState == null) {             Fragment fragment = ...             getSupportFragmentManager()                 .beginTransaction()                 .add(R.id.fragment_container, fragment)                 .commit();         }     } 

Since the system will indicate the activity is being recreated with a non-null Bundle for the savedInstanceState parameter, you check this to determine whether you should be creating and adding a new fragment.

Hope that helps.

like image 36
dominicoder Avatar answered Oct 13 '22 01:10

dominicoder