Search code examples
androidaction-menu

ActionBar menu refresh


I have a simple requirement where I have 2 menu items in action bar menu. The first is used to login using google account and the second is to log out. I want to hide one option based on the status of the user. i.e. if the user is logged in I want to hide its option and when he/she has logged out hide the logout option. Problem is after login is successful I am still seeing the login option. But when I click login again everything works. i.e. I see the logout option. I have also used the invalidateOptionsMenu() on login yet the menu is not refreshing the first time. But the logout works like a charm. Here is my code

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

        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        MenuItem login = menu.findItem(R.id.action_login);
        MenuItem logout = menu.findItem(R.id.action_logout);
        if(account!=null) {
            login.setVisible(false);
            logout.setVisible(true);
        } else {
            login.setVisible(true);
            logout.setVisible(false);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent(this, EditRssFeedActivity.class);
            startActivity(intent);
            return true;
        } else if (id == R.id.action_login) {

            signIn(mGoogleSignInClient);
            greetUser();
            invalidateOptionsMenu();
        } else if(id == R.id.action_logout) {
            mGoogleSignInClient.signOut()
                    .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(Task<Void> task) {
                            Toast.makeText(MainActivity.this,"User logged out",Toast.LENGTH_SHORT).show();
                        }
                    });
            invalidateOptionsMenu();
        }
        return super.onOptionsItemSelected(item);
    }

    private void signIn(GoogleSignInClient mGoogleSignInClient) {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        MenuItem item = findViewById(R.id.action_login);;
        if (requestCode == RC_SIGN_IN && item !=null) {
            item.setVisible(false);
            invalidateOptionsMenu();
            greetUser();
        }
    }

Can somebody help me trigger the menu refresh every time?


Solution

  • try this should work, by this we are hiding/displaying items after interaction with login or logout...

    MenuItem login;
    MenuItem logout;
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
    
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
       login = menu.findItem(R.id.action_login);
       logout = menu.findItem(R.id.action_logout);
        if(account!=null) {
            login.setVisible(false);
            logout.setVisible(true);
        } else {
            login.setVisible(true);
            logout.setVisible(false);
        }
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
    
        gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent(this, EditRssFeedActivity.class);
            startActivity(intent);
            return true;
        } else if (id == R.id.action_login) {
    
            signIn(mGoogleSignInClient);
            greetUser();
            logout.setVisible(true);
            login.setVisible(false);
        } else if(id == R.id.action_logout) {
            mGoogleSignInClient.signOut()
                    .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(Task<Void> task) {
                            Toast.makeText(MainActivity.this,"User logged out",Toast.LENGTH_SHORT).show();
                        }
                    });
            logout.setVisible(false);
            login.setVisible(true);
        }
        return super.onOptionsItemSelected(item);
    }
    
    private void signIn(GoogleSignInClient mGoogleSignInClient) {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
        super.onActivityResult(requestCode, resultCode, data);
        MenuItem item = findViewById(R.id.action_login);;
        if (requestCode == RC_SIGN_IN && item !=null) {
            item.setVisible(false);
            invalidateOptionsMenu();
            greetUser();
        }
    }
    

    hope this helps

    EDIT

    The onCreate method is called first, and before it finishes onCreateOptionsMenu is called.

    That will be true on devices and apps with an official Honeycomb-style action bar. If there is no action bar, onCreateOptionsMenu() should not get called until the user calls up the menu, typically by pressing the MENU button.