i want to add button on the actionbar of a fragment.But i'm getting error on this code given below.
this is my Fragment code where i want to add button on actionbar of this tab
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.credit_main, container, false);
return view;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// action with ID action_refresh was selected
case R.id.search:
Toast.makeText(getActivity(), "Refresh selected", Toast.LENGTH_SHORT)
.show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
here error is getMenuInflater(); cannot resolve
Step 1 : Make a xml of menu which you want to add.
<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" >
<item
android:id="#+id/item1"
android:title="#string/filter"
android:orderInCategory="10"
android:icon="#drawable/ic_launcher"
app:showAsAction="ifRoom" />
</menu>
Step 2:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Step 3:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_result, menu);
}
Step 4:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id == R.id.item1){
//What you want(Code Here)
return true;
}
return super.onOptionsItemSelected(item);
}
You have to call setHasOptionsMenu(true) to make it work.
Do something like:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
and then use the onCreateOptionsMenu() method with the inflater.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu items for use in the action bar
inflater.inflate(R.menu.search_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Take a look at setHasOptionsMenu() and onCreateOptionsMenu().
Related
I'm having a ToolBar made as ActionBar in a Fragment. I'm able to add ActionBar menu items but I'm not able to receive click response when I click on any ActionBar menu item.
I have read a lot of similar questions, I tried all but I'm still facing issue, so asked a question here.
The Fragment
public class DetailFragment extends Fragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
setHasOptionsMenu(true);
return inflater.inflate(R.layout.project_detail, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mToolBar = (Toolbar)view.findViewById(R.id.tb_toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(mToolBar);
mToolBar.setTitle(R.string.project_details);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.project_detail_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
// do something
break;
}
return true;
}
In my case in code above, onOptionsItemSelected is not even getting called.
Any pointers why ?
The Activity where I'm inflating this Fragment -
public class TestJust extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_just);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, new ProjectDetailFragment());
ft.commit();
}
}
project_detail_menu.xml -
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="#+id/options"
android:title="options"
android:icon="#android:drawable/ic_menu_more"
app:showAsAction="always"/>
</menu>
Most probably your problem is that you're always returning true from the activity's onOptionsItemSelected method.
When you return true, you consume the click event inside the method in the activity, that's why the click event never reaches the onOptionsItemSelected method inside your fragment.
Try this
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear()
inflater.inflate(R.menu.project_detail_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
// do something
return true;
default:
return super.onOptionsItemSelected(item);
}
Solution:
You are calling setHasOptionsMenu(true); in onCreateView()
Please call that method in onCreate()
Like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Calling this method in onCreate() ensures that the menu must participate in Fragment.
Then,
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu_items, menu);
}
Finally,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
// do something
break;
}
return super.onOptionsItemSelected(item);
It should work now.
initialize option in onCreateOptionMenu then check it. you only inflate menu, use without initialize option, first initialize then use it.
like: MenuItem item = menu.findItem(R.id.option);
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
MenuItem item = menu.findItem(R.id.option);
}
switch (item.getItemId()) {
case R.id.options:
// do something
return true;//<- Here you need to return true because breaking compile from this line returns default false;
default:
return super.onOptionsItemSelected(item);
}
I have created a fragment with action bar menu, that menu was shown but not working when its clicked.
Here is My Fragment:
public class ComposeFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_compose, container, false);
userName = (TextView) view.findViewById(R.id.user_name);
subjectSpinner = (Spinner) view.findViewById(R.id.subject_spinner);
sendButton = (Button) view.findViewById(R.id.send_btn);
messageEditText = (EditText) view.findViewById(R.id.message);
userName.setText(Ezcation.getInstance().userName);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.compose_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.e("Menu","Before Switch");
switch (item.getItemId()){
case R.id.sent:
Log.e("Menu","Sent");
if (messageEditText.getText().toString().equals("")){
messageEditText.setError("Please Enter your Message");
}else {
sendMessage(messageEditText.getText().toString());
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.messageActivity = (MessageActivity) context;
SpannableString s = new SpannableString("Compose Message");
s.setSpan(new TypefaceSpan(messageActivity, "Miller-Text.ttf"), 0, s.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
messageActivity.setTitle(s);
}
}
When menu was clicked even Log.e("Menu","Before Switch"); not working.
My Menu xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/sent"
android:title="Sent"
android:orderInCategory="10"
android:icon="#drawable/sent"
app:showAsAction="ifRoom" />
</menu>
For Future visiters you should use this in Activity class:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
To work properly hardcoding false isnt the right way
add this in your Activity.
#Override public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);;
}
The super call is missing inside onCreateOptionsMenu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.compose_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
I have an ActionBarActivity and one Fragment. The Activity has no menu inflated, while the Fragment has a menu with two buttons. Fragment menu is visible, but the buttons don't react at all when tapped. At debugging I can see that both onCreateOptionsMenu() for Fragment and Activity get called, but when tapping buttons no onOptionsItemSelected() gets called, neither from Activity nor from Fragment.
Activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return false;
}
Fragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivity = (NavigationActivity)getActivity();
setHasOptionsMenu(true);
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState){
return (ScrollView) inflater.inflate(R.layout.tutoring_detail, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.query_details_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.accept_query:
respondToQuery(true);
return true;
case R.id.decline_query:
respondToQuery(false);
return true;
default:
break;
}
return false;
}
Menu to be displayed in Fragment
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<item
android:id="#+id/accept_query"
android:orderInCategory="100"
app:showAsAction="always"
android:checkable="true"
style="?android:attr/borderlessButtonStyle"
app:actionViewClass="android.widget.ImageButton"/>
<item
android:id="#+id/decline_query"
android:orderInCategory="101"
app:showAsAction="always"
android:checkable="true"
style="?android:attr/borderlessButtonStyle"
app:actionViewClass="android.widget.ImageButton"/>
</menu>
In the Activity class,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
return false;
}
In the Fragment,
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Toast.makeText(getActivity(), "called " + item.getItemId(), Toast.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
You must use super.onOptionsItemSelected(item) in the parent activity's onOptionsItemSelected(...) method.
From Activity | Android Developers:
Derived classes should call through to the base class for it to perform the default menu handling.
Try moving setHasOptionsMenu(true) inside of the onCreateView() method in your Fragment instead of onCreate().
I had a similar issue after making special layout for my action button (I made an Image Button and needed to pad it and change some other things so I had to use layout for it).
Then onOptionsItemSelected lost connection with this imageButton so I just use clickListener for it inside onCreateOptionsMenu. It might not be the best practice, maybe there is a better solution, but this is what solve my problem.
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.picker_list_menu, menu);
MenuItem itemDone = menu.findItem(R.id.menu_done);
MenuItemCompat.setActionView(itemDone, R.layout.menu_layout_done);
menuDoneIB = (ImageButton) MenuItemCompat.getActionView(itemDone);
itemDone.getActionView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//your code..
}
});
}
Try using oncreateview
public static class ExampleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
If you have dynamically changed menu item, for instance, a badge menu (https://stackoverflow.com/a/16648170/2914140 or https://stackoverflow.com/a/26017587/2914140), you should initialize the item in onCreateOptionsMenu and re-set setOnClickListeners after every change of the item.
In my case:
private MenuItem menuItem;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_catalog, menu);
menuItem = menu.findItem(R.id.action_badge);
writeBadge(0);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_badge) {
// Your code.
return true;
}
return super.onOptionsItemSelected(item);
}
private void writeBadge(int count) {
MenuItemCompat.setActionView(menuItem, R.layout.item_badge);
RelativeLayout layout = (RelativeLayout) MenuItemCompat.getActionView(menuItem);
// A TextView with number.
TextView tv = (TextView) layout.findViewById(R.id.badge);
if (count == 0) {
tv.setVisibility(View.INVISIBLE);
} else {
tv.setVisibility(View.VISIBLE);
tv.setText(String.valueOf(count));
}
// An icon, it also must be clicked.
ImageView imageView = (ImageView) layout.findViewById(R.id.image);
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
onOptionsItemSelected(menuItem);
}
};
menuItem.getActionView().setOnClickListener(onClickListener);
imageView.setOnClickListener(onClickListener);
}
I am passing the click event to fragment from the activity. This worked for me.
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
return getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getFragments().size() - 1)
.onOptionsItemSelected(item);
}
How should I access the actionbar's menu items in fragment ?
I have tried this but nothing happened
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.menu_refresh:
Toast.makeText(getActivity().getApplicationContext(), "clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
}
Follow this steps:
Add setHasOptionsMenu(true) method in your Fragment.
Override onCreateOptionsMenu(Menu menu, MenuInflater inflater) and
onOptionsItemSelected(MenuItem item) methods in your Fragment.
Inside your onOptionsItemSelected(MenuItem item) Activity's method,
make sure you return false when the menu item action would be
implemented in onOptionsItemSelected(MenuItem item) Fragment's
method.
Example:
Activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.activity_menu_item:
// Do Activity menu item stuff here
return true;
case R.id.fragment_menu_item:
// Not implemented here
return false;
default:
break;
}
return false;
}
Fragment
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
....
}
#Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
// Do something that differs the Activity's menu here
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.activity_menu_item:
// Not implemented here
return false;
case R.id.fragment_menu_item:
// Do Fragment menu item stuff here
return true;
default:
break;
}
return false;
}
In your fragments onCreate method add setHasOptionsMenu(true);.
If your fragment is in a ViewPager then the fragment with the ViewPager also needs the above line.
You cant access directly ActionBar menu items in a Fragment.
What you can do is put setHasOptionsMenu(true); in onCreateView function in fragment class and this calls the function onCreateOptionsMenu(Menu menu) in the corresponding activity.
There, you can access all the menu items you have in the action bar.
You can use:
MenuItem item = menu.getItem(index);
You have one example of using this:
in fragment onCreateView class:
setHasOptionsMenu(true);
in corresponding activity class:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
MenuItem item = menu.getItem(0);
if(condition)
item.setVisible(true);
else
item.setVisible(false);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.action_logout:
makeLogout();
return true;
default :
return super.onOptionsItemSelected(item);
}
}
One thing I would add to this (my reputation does not allow me to comment) and reason it was not working for me.
Make sure your fragment's hosting activity extends AppCompatActivity not FragmentActivity!
public class MainActivity extends AppCompatActivity {
}
From the Google Reference Documentation for FragmentActivity:
Note: If you want to implement an activity that includes an action bar, you should instead use the ActionBarActivity class, which is a subclass of this one, so allows you to use Fragment APIs on API level 7 and higher.
ActionBarActivity now being deprecated, use AppCompatActivity instead. When using AppCompatActivity, also make sure you set "the activity theme to Theme.AppCompat or a similar theme" (Google Doc too).
android.support.v7.app.AppCompatActivity is a subclass of the android.support.v4.app.FragmentActivity class (see AppCompatActivity ref doc).
Menu item main.xml file :
<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="dbl.contact.manager.MainActivity" >
<item
android:id="#+id/menu_search"
android:actionLayout="#layout/action_bar"
android:icon="#drawable/searchagain"
android:orderInCategory="0"
android:showAsAction="always"
android:title="search"/>
</menu>
This is Menu item. custom action bar like edittext in the action bar You have to create a custom layout. Here custom action_bar.xml file :
<?xml version="1.0" encoding="utf-8"?>
<EditText
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/inputSearch"
android:layout_width="280dp"
android:layout_height="40dp"
android:cursorVisible="true"
android:hint="Search"
android:imeOptions="actionDone"
android:inputType="text"
android:textColor="#android:color/white"
android:textCursorDrawable="#android:color/white" />
Then in the fragment class you to override. Just Copy and paste this code.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
super.onCreateOptionsMenu(menu, inflater);
getActivity().getMenuInflater().inflate(R.menu.main, menu);
View v = (View) menu.findItem(R.id.menu_search).getActionView();
inputSearch = (EditText)v.findViewById(R.id.inputSearch);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
// clientAdapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
// ListData.this.clientAdapter.getFilter().filter(s);
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
adapter.getFilter().filter(s.toString());
}
});
}
My meny code is:
<item android:id="#+id/action_map"
android:icon="#android:drawable/ic_dialog_map"
android:title="Add"
android:showAsAction="ifRoom"/>
<item
android:id="#+id/action_settings"
android:showAsAction="never"
android:title="#string/action_settings" />
</menu>
My Fragment code is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_where_am_i, container, false);
setHasOptionsMenu(true);
return root;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.where_i_am_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_settings:
startActivity(new Intent(getActivity(), SettingsActivity.class));
return true;
case R.id.action_map:
return true;
}
return super.onOptionsItemSelected(item);
}
And i get next action bar. Why i have 2 settings in that list? And i don't want to add label "Add" to that list, hiw can i make it?
You should clear the menu:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.where_i_am_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Hope it helps you :)