toolbar menu item click in fragments
Asked Answered
B

5

22

I know this question has been asked and but I am unable to solve my problem after looking at those answer. I have an Activity with a Fragment. In fragment, I have added the toolbar and I want to handle toolbar menu item click events from the fragments.

In menu, I have added a single share button. I am getting the click event callback for the Up navigation (arrow home button) but I am not getting click event callback for the share button in my fragment.

Can some points me at what I am doing wrong here.

menu.xml

<menu 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" 
     tools:context="com.rahul.haridasasampada.details.DescriptionActivity">
     <item
         android:id="@+id/action_share"
         android:title="Share"
         android:orderInCategory="100"
         app:showAsAction="always"           
         app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
 </menu> 

I have added toolbar to the fragment layout. My Activity's code -

public class DescriptionActivity extends ActionBarActivity {



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

        if (savedInstanceState == null) {
            Article articleExtra = (Article) getIntent().getParcelableExtra(DescriptionFragment.ARGS_EXTRA);
            DescriptionFragment descriptionFragment = DescriptionFragment.newInstance(articleExtra);
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, descriptionFragment)
                    .commit();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        getSupportActionBar().setTitle(R.string.app_name_in_kannada);
    }

    @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_description, menu);
        Log.d("debug", "activity : onCreateOptionsMenu");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                Log.d("debug","activity: action home has clicked");
                onBackPressed();
                return false;
            case R.id.action_share:
                Log.d("debug","activity: action share has clicked");
                return false;
        }

        return super.onOptionsItemSelected(item);
    }


}

My Fragments code -

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    // some code
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ActionBarActivity actionBarActivity = (ActionBarActivity) getActivity();
    Toolbar toolbar = (Toolbar) getView().findViewById(R.id.toolbar_actionbar);
    actionBarActivity.setSupportActionBar(toolbar);
    toolbar.setOnMenuItemClickListener(this);
    toolbar.inflateMenu(R.menu.menu_description);
}

@Override
public boolean onMenuItemClick(MenuItem menuItem) {
    switch (menuItem.getItemId()) {
        case R.id.action_share:
            if (menuItem.getItemId() == R.id.action_share)
                Log.d("debug","action share has clicked");
            return true;
    }
    return false;
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    Log.d("debug", "fragment : onCreateOptionsMenu");
    MenuItem shareMenuItem = menu.findItem(R.id.action_share);
    mShareActionProvider =(ShareActionProvider)MenuItemCompat.getActionProvider(shareMenuItem);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case android.R.id.home:
            Log.d("debug","fragment : action home has clicked");
            return true;
        case R.id.action_share:
            Log.d("debug","fragment: action share has clicked");
            return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View detailFragmentView = inflater.inflate(R.layout.fragment_description, null);

    return detailFragmentView;
}
Boccie answered 6/5, 2015 at 10:53 Comment(5)
why you put ToolBar in your fragment? it is should be in ActivityDelight
I am using a master-detail flow and I have read some where that we should be using toolbar inside the fragments.Boccie
But you setSupportActionBar(mToolbar); to activity, can you?Delight
@Delight Yes, I am setting this to the Activity because of the up navigation offered by the Action bar.Boccie
Ok just made a answer for your issue, hope it worksDelight
D
25

From Android Docs, for Fragment:

public void onCreateOptionsMenu (Menu menu, MenuInflater inflater)

Initialize the contents of the Activity's standard options menu. You should place your menu items in to menu. For this method to be called, you must have first called setHasOptionsMenu(boolean).

so you want to control actionbar menu in Fragment, then you have to call setHasOptionsMenu method better in Fragment's onCreate(...):

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

also important is that you should not use inflateMenu and onCreateOptionsMenu both together for same ToolBar, inflateMenu is for standalone without setting ToolBar as ActionBar.


Suggestion:

keep one ToolBar in Activity as ActionBar for your App, and another ToolBar standalone inside Fragment.

Hope this help!

Delight answered 6/5, 2015 at 13:17 Comment(7)
Yes, I have written setHasOptionsMenu(true); but not working. Please check my full activity and fragment code. Also, it should work without using Toolbar.inflateMenu(). check this #26512481Boccie
what's Toolbar.inflateMenu()Delight
@Xchinegn, this is what mustafasevgi has suggested. Check his answerBoccie
Ok mustafasevgi's solution is for standalone, but if you use standalone then you should not set ToolBar as ActionBar, right?Delight
Yes, I have added the standalone toolbar in my fragment completely without using the actionbar at all.Boccie
Suggestion to keep one ToolBar in Activity as ActionBar for your App, and another ToolBar standalone inside Fragment, agree?Delight
You rock. I searched whole world and this is what solved for me!!! Love youLoath
S
16
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;


public class MyFragment extends Fragment implements Toolbar.OnMenuItemClickListener {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_list, container, false);

        Toolbar toolbar= (Toolbar) getActivity().findViewById(R.id.toolbar);
        toolbar.inflateMenu(R.menu.menu_main);
        toolbar.setOnMenuItemClickListener(this);

        return rootView;
    }


    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.action_menu:
                //do sth here
                return true;
        }
        return false;
    }
Significs answered 16/3, 2016 at 20:38 Comment(2)
Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others.Hyderabad
This option is not suitable, once you'll have all the other activities showing the same menu item.Picayune
D
11
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
 {
   View v = inflater.inflate(R.layout.training1_fragment, container, 
              false);

       setHasOptionMenu(true);

       return v;
 }

@Override
 public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
    case R.id.action_save : 
       {
       //Write here what to do you on click
        return true;
     }
   }
  return super.onOptionsItemSelected(item);
 }
Darsey answered 4/12, 2015 at 9:54 Comment(2)
Where is break in switch case?Bidle
@ArthTilva return true; does the trick. And also, a return false is missing before ending the switch.Cathe
M
1

You should getPointer toolbar from your activity class and inflate menu in fragment class.

You can look this ex:

 @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        activity = ((DescriptionActivity ) getActivity());
        Toolbar tollbar=getView.findViewById(R.id.your_toolbar);
        activity.setSupportActionBar(toolbar);
        activity.toolbar.inflateMenu(R.menu.menu_search); 
        activity.toolbar.setOnMenuItemClickListener(this);     

    }



@Override
public boolean onMenuItemClick(MenuItem menuItem) {
    switch (menuItem.getItemId()) {
        case R.id.action_search:              
            break;
    }
    return false;
}
Maltzman answered 6/5, 2015 at 11:11 Comment(6)
Thanks @mustafasevgi, but I am using master-detail flow and I want toolbar for my detailed fragment.Boccie
I have tried this but its not working. Also, toolbar is in fragment right? then why have you written 'activity.toolbar.setOnMenuItemClickListener(this); 'Boccie
I have made changes in the code(inside the fragment) as you suggested, but its not working. Any help will be appreciated.Boccie
@RahulChaurasia please can you add full your activity code?Maltzman
@RahulChaurasia DescriptionActivity actionBarActivity = (DescriptionActivity ) getActivity();Maltzman
check this link #26512481Boccie
F
0

Please refer this for click of the Fragment optionMenu click link.

Fumatorium answered 3/5, 2021 at 9:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.