SearchView with SherlockActivity returns null on getActionView() - java

I've been transitioning an Android application developed with Eclipse over to Android Studio. It targets a minimum API level of 10 (current 22) and uses ActionBarSherlock (huge bummer). With Eclipse, it was making use of ActionBarSherlock 4.2 in a library project, but now it seems the only way to use ActionBarSherlock is with 4.4 as an AAR with gradle. compile 'com.actionbarsherlock:actionbarsherlock:4.4.0#aar'
After getting everything migrated, the app now crashes whenever the SearchView is used on Android 2.3.5 (works fine on Android 4). The problem is in onCreateOptionsMenu menu.findItem(R.id.search_menu_item).getActionView() which returns null. Here's what my SearchActivity class looks like:
public class SearchActivity extends SherlockActivity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_view);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
mListView = (ListView) findViewById(R.id.search_view_list);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.search_menu, menu);
//Get the action view of the menu item whose id is search
SearchView searchView = (SearchView) menu.findItem(R.id.search_menu_item).getActionView();
searchView.setQueryHint("Search for ISBN, UPC, EAN or Title");
final Menu savedMenu = menu;
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query) {
//Toast.makeText(getApplicationContext(), query, Toast.LENGTH_SHORT).show();
if (mOnlineSearchTask == null)
{
mOnlineSearchTask = new OnlineSearchTask(getBaseContext());
mOnlineSearchTask.execute(query, "title", "All");
((SearchView) savedMenu.findItem(R.id.search_menu_item).getActionView()).clearFocus();
}
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
}
);
searchView.setIconified(false);
return true;
}
}
search_view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/search_view_list"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</ListView>
</RelativeLayout>
search_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<item android:id="#+id/search_menu_item"
android:title="Search"
android:icon="#drawable/ic_search_inverse"
android:showAsAction="always"
android:actionViewClass="com.actionbarsherlock.widget.SearchView" />
</menu>

Try changing your xml file (search_menu.xml) to :
<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<item android:id="#+id/search_menu_item"
android:title="Search"
android:icon="#drawable/ic_search_inverse"
android:showAsAction="always"
app:actionViewClass="com.actionbarsherlock.widget.SearchView" />
</menu>
It looks almost the same (because it's really similiar) - I changed the last line from android:actionViewClass.... to app:actionViewClass...

Related

Change the appearance of Android Search Dialog

I am trying to implement search functionality into an android app using the Search Dialog. After following the documentation, I got this search dialog when pressing the search button in my app.
As you can see, the search dialog is too small( the app bar can be seen below it), it is not centered, and contains the app icon near the back button.
The Search Dialog showed in the guide is centered vertically in the app bar and doesn't have the app icon near the back button, which is what I want to do for my search dialog as well. But I can't seem to find any resource on how to do it. Can anyone help me out?
Thanks in advance!
Edit: Here is the code that enables the Search Dialog
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val root = binding.root
setContentView(root)
//Setup the app bar
setSupportActionBar(binding.toolbar);
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater = menuInflater;
inflater.inflate(R.menu.app_bar_menu, menu)
return true;
}
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.action_search -> {
onSearchRequested()
true
}
else -> {
super.onOptionsItemSelected(item)
}
}
}
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/search_hint"
android:label="#string/app_name">
</searchable>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:title="#string/app_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
Using the method that you want for create a search dialog, this is the most similar aspect that it can achieve:
https://i.stack.imgur.com/hwTlF.png
This is the code that I implemented:
MainActivity.class code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#SuppressLint("ResourceType")
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(true);
searchView.setIconified(false);
//Here you can set the parameters of the search view
return true;
}
I created a menu resource file called options_menu.xml and that's the code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/search"
android:title="title"
android:icon="#drawable/search_icon"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.widget.SearchView" />
</menu>
And the searchable xml file called search.xml
<?xml version="1.0" encoding="utf-8"?>
<Searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="Your hint"
android:label="Label text">
</Searchable>
I created the icon of the menu in the drawable folder but you can change to other icon if you want.
Also I leave several links to all the customizations that you can add to the searchView:
https://developer.android.com/guide/topics/search/searchable-config
https://developer.android.com/reference/android/widget/SearchView
I hope this is the right solution for you.
I made a different search method, I used the Android Studio search view,
that's the main activity code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem item = menu.findItem(R.id.mySearchButton);
SearchView searchView = (SearchView)item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
You have to create an Android Resource File, select resource type "menu", and call it as you want, after that, add this item:
<item android:id="#+id/mySearchButton"
android:title="Button"
android:icon="#drawable/search_icon"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always"/>
This code worked for me, images here:
https://i.stack.imgur.com/XNRZy.png
https://i.stack.imgur.com/hUt4x.png
I hope it works for you aswell.

Menu won't show in Activity

I have a menu that won't show up in my activity. I have a main activity and a separate activity that contains a list of items I want the user to be able to search through. However, the menu isn't showing up in the activity for searching, so nothing happens when entering in a string for the search.
The goal was the get the menu in the search activity in order to allow the user to search through items using a SearchView and RecyclerView
I'm very new to Android Studio, so any help would be greatly appreciated.
Here is the menu for the SearchView
<?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/action_search"
android:icon="#drawable/ic_search"
android:title="Search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
/>
<item android:id="#+id/action_search2"
android:icon="#drawable/ic_search"
android:title="Search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
/>
</menu>
Here is the layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<include
layout="#layout/activity_search_toolbar"/>
<android.support.v7.widget.SearchView
android:id="#+id/action_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:menu="#menu/search_menu">
</android.support.v7.widget.SearchView>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme">
<Button
android:id="#+id/GoBackbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GO BACK" />
<!--<android.support.v7.widget.SearchView-->
<!--android:id="#+id/searchBar"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content">-->
<!--<!–app:menu="#menu/search_menu"–>-->
<!--</android.support.v7.widget.SearchView>-->
</android.support.v7.widget.Toolbar>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
and the toolbar to add to the layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/search_toolbar"
android:background="?attr/colorPrimary">
</android.support.v7.widget.Toolbar>
Here is where I inflate the search_menu
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
return true;
}
Finally this is part of my Adapter class to filter the items in a RecyclerView
#Override
public Filter getFilter() {
return locationFilter;
}
private Filter locationFilter = new Filter(){
#Override
protected FilterResults performFiltering(CharSequence constraint){
List<Location> filteredLocationList = new ArrayList<>();
if(constraint == null || constraint.length() == 0){
filteredLocationList.addAll(locationListFull);
} else{
String filterPattern = constraint.toString().toLowerCase().trim();
for(Location location : locationListFull){
if(location.getTitle().toLowerCase().contains(filterPattern)){
filteredLocationList.add(location);
}
// Add another if statement here if we want to be able to search
// descriptions as well
}
}
FilterResults results = new FilterResults();
results.values = filteredLocationList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results){
locationList.clear();
locationList.addAll((List)results.values);
notifyDataSetChanged();
}
};
Also if there's another way to use the SearchView with RecyclerView besides creating a menu for the SearchView, that would be very helpful. I have tried researching ways to access the SearchView besides through creating a new menu, but haven't found anything useful.
Prepare the Screen's standard options menu to be displayed. This is called right before the menu is shown, every time it is shown. You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents.
https://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu(android.view.Menu)
You need to override onPrepareOptionsMenu and setup your searchview there instead of doing that in onCreateOptionsMenu

OnOptionsItemSelected doesn't work on android API 19 (but works on android 24)

I have the following code in my activity class
public class admin_fab_features_grid extends
base_activity_for_admin_home_page implements Parcelable {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity_context = getApplicationContext();
Intent iIntent= getIntent();
Bundle b = iIntent.getExtras();
// display the admin_fab_features_grid that contain the dashboard list of all the admin options
setContentView(R.layout.admin_fab_features_grid);
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar_toolbar);
setSupportActionBar(toolbar);
}
The base_activity_for_admin_home_page.java has the following code
public class base_activity_for_admin_home_page extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(Tag, " Into base activity for parent menu");
_context = getApplicationContext();
// display the admin_fab_features_grid that contain the dashboard list of all the admin options
setContentView(R.layout.admin_fab_features_grid);
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar_toolbar);
setSupportActionBar(toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_admin_home_page, menu);
Log.d(Tag, "inflate done");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.actionbar_settings:
return true;
}
}
}
The menu_admin_home_page has the following 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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MyActivity">
<item android:id="#+id/actionbar_settings"
android:title="#string/actionbar_settings"
android:orderInCategory="100"
app:showAsAction="never" />
<!--
<item android:id="#+id/actionbar_dropoff"
android:title="#string/actionbar_dropoff"
android:orderInCategory="90"
app:showAsAction="never" />
<item android:id="#+id/actionbar_signin"
android:title="#string/actionbar_signin"
android:orderInCategory="85"
app:showAsAction="never" />
-->
<item android:id="#+id/actionbar_logout"
android:title="#string/actionbar_logout"
android:orderInCategory="80"
app:showAsAction="never" />
</menu>
The "Settings" menu is enabled in the Toolbar. I can see ":" in the Toolbar. On a device that has Android API24 I am able to click on it and the OnOptionsItemSelected function is getting called. But the same application on a device that has Android API 19 the OnOptionsItemSelected does not get called. Can someone help?
change onOptionsItemSelected() to this and try
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.actionbar_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
Since you set the showAsAction attribute to never, then these menu items will never show as action views. Try this:
showAsAction = ifRoom|withText
switch (item.getItemId()) {
case R.id.actionbar_settings:
doyouraction();
return true;
default: return super.onOptionsItemSelected(item);
} }
Solved it after 4 days of pain.
What occurred is that the CoordinatorLayout overlays the GridView on top of the toolbar and that is why the onOptionsItemSelected icons were not getting called. They're being blocked. Toolbar doesn't overlay on-top of the GridView like an actionbar. Its a view itself. To solve this I removed the CoordinatorLayout add an id to the Toolbar and then add android:layout_below="#id/toolbar".
<?xml version="1.0" encoding="utf-8"?>
<!--
// <android.support.design.widget.CoordinatorLayout
-->
<LinearLayout
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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="fab_features.admin_fab_features_grid">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#id/app_bar_toolbar"
style="#style/Widget_v7_Toolbar_style"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.Toolbar
android:id="#id/app_bar_toolbar"
style="#style/Widget_v7_Toolbar_style"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#id/admin_fab_features_grid"
style="#style/admin_fab_features_grid_gridview"
android:layout_below="#id/app_bar_toolbar"
/>
</LinearLayout>

Menu item block Toast [duplicate]

Is some possible way how to hide the toast after long-press on the ActionBar item? I didn't setup a title for the item but it is still there - empty toast.
<item
android:id="#+id/ab_main_menu_dots"
android:icon="#drawable/action_icons_dots"
android:showAsAction="always">
<menu>
<item
android:id="#+id/ab_main_menu_my_profile"
android:showAsAction="never"
android:title="#string/ab_my_profile">
</item>
<item
android:id="#+id/ab_main_menu_settings"
android:showAsAction="never"
android:title="#string/menu_settings">
</item>
<item
android:id="#+id/ab_main_menu_help"
android:showAsAction="never"
android:title="#string/tv_help_login">
</item>
<item
android:id="#+id/ab_main_menu_about_us"
android:showAsAction="never"
android:title="#string/ab_about_us">
</item>
<item
android:id="#+id/ab_main_menu_logout"
android:showAsAction="never"
android:title="#string/bt_logout_main">
</item>
</menu>
</item>
The only way to hide the toast is when you set the ActionBar menu item to be displayed with text. android:showAsAction="withText". Otherwise the toast adds clarification of what each action item represents even if there is no title set for menu item.
Probably the cleanest way to go about this is to assign a custom action view to your menu item that mimics the look of a regular one.
Since you mentioned you're using ActionBarSherlock, here's a simple example.
Imagine the following menu.xml, which gets inflated in an Activity.
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/ab_main_menu_dots"
android:actionLayout="#layout/ab_main_menu_dots_layout"
android:showAsAction="always"/>
</menu>
You can define ab_main_menu_dots_layout.xml to mimic the overflow button like this:
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/Widget.Sherlock.ActionButton.Overflow"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The result is a menu item that looks like an overflow button and does not display a Toast message when you long-press it, regardless of whether the native ActionBar is used or ABS. Up to you to take it from here. You want to reconsider and abide by the guidelines instead.
You can modify onLongClickin ActionMenuItemView Class to stop Toasting on long click.
but be careful, It's only working on devices with API less than 11, because sherlockactionbar library checking your device API level by Build.VERSION.SDK_INT and if you have newer device it just use default system actionbar which you're not modifying.
In onCreateOptionsMenu schedule a task to disable long click on desired menu item. Here is the sample
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.my_menu, menu);
new Handler().post(new Runnable() {
#Override
public void run() {
final View v = getActivity().findViewById(R.id.your_menu_item);
if (v != null) {
v.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return false;
}
});
}
}
});
}
This is how I did it:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem item = menu.findItem(R.id.no_toast);
item.setActionView(R.layout.custom_view);
item.getActionView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle click (just this item)
}
});
return true;
}
and this is my menu:
<?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:title="Never gonna see me in a toast!"
app:showAsAction="always"
android:id="#+id/no_toast" />
</menu>
my custom view is just an ImageButton:
<?xml version="1.0" encoding="utf-8"?>
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="#style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/icon" />
Note: don't forget to set style, Widget.AppCompat.Toolbar.Button.Navigation makes IamgeButton to be shown correctly in toolbar.
P.S: Personally I prefer the default behavior but this was my case:
I disabled right to left support for my application and after that when I set default locale to a rtl language, toast was showing up in the wrong side! Honestly I was in hurry and didn't find out the reason but I'll appreciate if someone let me know the why, anyway this is how I passed through.
You can achieve this by using custom action view as follow:
action_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:support="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/item1"
support:showAsAction="always">
</item>
</menu>
custom_action_view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:paddingRight="5dp" >
<ImageButton
android:id="#+id/customActionItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="#drawable/abc_item_background_holo_dark"
android:src="#drawable/bulb_icon" />
</RelativeLayout>
and menu inflater code is as follow:
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_menu, menu);
final MenuItem item1= menu.findItem(R.id.item1);
MenuItemCompat.setActionView(item1, R.layout.custom_action_view);
View vItem1= MenuItemCompat.getActionView(item1);
final ImageButton customActionItem= (ImageButton) vItem1.findViewById(R.id.customActionItem);
customActionItem.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// do something here
}
});
return super.onCreateOptionsMenu(menu);
}
You could try to create your own custom ActionBar. Here is a tutorial on how to do that:
Custom Action Bar
For me the solution was using:
android.support.v4.view.MenuItemCompat
So instead of inflating the menu from the XML:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.refresh_menu, menu);
return true;
}
I created the items programmatically using MenuItemCompat:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem refreshItem = menu.add(Menu.NONE, R.id.menu_item_refresh, Menu.NONE, R.string.general_pop_up_dialog_btn_cancel);
MenuItemCompat.setActionView(refreshItem, R.layout.actionbar_custom_view_refresh);
MenuItemCompat.setShowAsAction(refreshItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
return true;
}
There is a way, if you're using ActionBarSherlock. Find the ActionMenuItemView.java file in library and just comment whole onLongClick method.

How to set menu to Toolbar in Android

I want use ToolBar instead of ActionBar, but don't show me menu in toolbar!!! i want set menu such as Refresh or Setting buttons in ActionBar.
Toolbar.xml code :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:navigationContentDescription="#string/abc_action_bar_up_description"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="Main Page"
android:gravity="center"/>
MainPage.java code:
public class MainPage extends AppCompatActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_page);
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle("Main Page");
}
toolbar.setSubtitle("Test Subtitle");
toolbar.inflateMenu(R.menu.main_menu);
}
}
main_menu.xml code :
<?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/menu_main_setting"
android:icon="#drawable/ic_settings"
android:orderInCategory="100"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
<item
android:id="#+id/menu_main_setting2"
android:icon="#drawable/ic_settings"
android:orderInCategory="200"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
</menu>
How to fix this problem and show menu in Toolbar ? thanks all dears <3
just override onCreateOptionsMenu like this in your MainPage.java
#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, menu);
return true;
}
Don't use setSupportActionBar(toolbar)
I don't know why but this works for me.
toolbar = (Toolbar) findViewById(R.id.main_toolbar);
toolbar.setSubtitle("Test Subtitle");
toolbar.inflateMenu(R.menu.main_menu);
For menu item click do this:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.item1) {
// do something
} else if (item.getItemId() == R.id.filter) {
// do something
} else {
// do something
}
return false;
}
});
Will update the why part of this answer when I find a proper explanation.
Here is a fuller answer as a reference to future visitors. I usually use a support toolbar but it works just as well either way.
1. Make a menu xml
This is going to be in res/menu/main_menu.
Right click the res folder and choose New > Android Resource File.
Type main_menu for the File name.
Choose Menu for the Resource type.
Paste in the following content as a starter.
<?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/action_add"
android:icon="#drawable/ic_add"
app:showAsAction="ifRoom"
android:title="Add">
</item>
<item
android:id="#+id/action_settings"
app:showAsAction="never"
android:title="Settings">
</item>
</menu>
You can right click res and choose New image asset to create the ic_add icon.
2. Inflate the menu
In your activity add the following method.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
3. Handle menu clicks
Also in your Activity, add the following method:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_add:
addSomething();
return true;
case R.id.action_settings:
startSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Further reading
Android Menu Documentation
You need to override this code in your Activity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu, this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main2, menu);
return true;
}
and set your toolbar like this:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
You can still use the answer provided using Toolbar.inflateMenu even while using setSupportActionBar(toolbar).
I had a scenario where I had to move toolbar setup functionality into a separate class outside of activity which didn't by-itself know of the event onCreateOptionsMenu.
So, to implement this, all I had to do was wait for Toolbar to be drawn before calling inflateMenu by doing the following:
toolbar.post {
toolbar.inflateMenu(R.menu.my_menu)
}
Might not be considered very clean but still gets the job done.
First way:
In activitymain.xml
<androidx.appcompat.widget.Toolbar
android:id="#+id/maintoolbar"
android:layout_width="match_parent"
android:layout_height="56dp"/>
In MainActivity.java
import androidx.appcompat.widget.Toolbar;
private Toolbar toolbar;
Inside onCreate method-
toolbar=findViewById(R.id.maintoolbar);
setSupportActionBar(toolbar);
Inside your MainActivity class-
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.<your menu xml file name here>,menu);
return super.onCreateOptionsMenu(menu);
}
Second way :
//Remove setSupportActionBar(toolbar) and onCreateOptionmenu.
toolbar=findViewById(R.id.maintoolbar);
toolbar.inflateMenu(R.menu.<your menu xml file name here>);
Also you need this, to implement some action to every options of menu.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_help:
Toast.makeText(this, "This is teh option help", Toast.LENGTH_LONG).show();
break;
default:
break;
}
return true;
}
Without ActionBar but with Toolbar
If you want to use a Toolbar instead of the ActionBar, to setSupportActionBar is contradiction in principle as #RohitSingh answered above.
You need neither to use setSupportActionBar nor to override onCreateOptionsMenu and onOptionsItemSelected which are used for the ActionBar.
NoActionBar theme
Place a Toolbar in the layout xml
Prepare a menu xml
Toolbar#inflateMenu (alternatively you can also set a menu in the layout xml)
Toolbar#setOnMenuItemClickListener
Below is an example.
1. NoActionBar theme
(MaterialCompolent.DayNight theme is used in this sample)
<style name="Theme.AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
2. Place a Toolbar in the layout
(MaterialToobar is used in this sample)
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
3. Prepare a menu xml
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/item1"
android:title="#string/item1"
app:showAsAction="ifRoom" />
<item
android:id="#+id/item2"
android:title="#string/item2"
app:showAsAction="ifRoom" />
</menu>
4. Toolbar#inflateMenu
binding.toolbar.inflateMenu(R.menu.main); // binding is a ViewBinding
5. Toolbar#setOnMenuItemClickListener
Recent Android recommend to avoid to use switch to differentiate ids. Using a normal if ~ else if ~ else block is desirable. In addition to that, we can use lambda in Java 8.
binding.toolbar.setOnMenuItemClickListener(menuItem -> {
int itemId = menuItem.getItemId();
if (itemId == R.id.item1) {
// do something for item1
return true;
} else if (itemId == R.id.item2) {
// do something for item2
return true;
} else {
// if you do nothing, returning false should be appropriate.
return false;
}
});
Although I agree with this answer, as it has fewer lines of code and that it works:
How to set menu to Toolbar in Android
My suggestion would be to always start any project using the Android Studio Wizard. In that code you will find some styles:-
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
and usage is:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
Due to no action bar theme declared in styles.xml, that is applied to the Main Activityin the AndroidManifest.xml, there are no exceptions, so you have to check it there.
<activity android:name=".MainActivity" android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
The Toolbar is not an independent entity, it is always a child
view in AppBarLayout that again is the child of
CoordinatorLayout.
The code for creating a menu is the standard code since day one,
that is repeated again and again in all the answers, particularly
the marked one, but nobody realized what is the difference.
BOTH:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
AND:
How to set menu to Toolbar in Android
WILL WORK.
Happy Coding :-)
In XML add one line inside
<com.google.android.material.appbar.MaterialToolbar app:menu="#menu/main_menu"/>
In java file
Remove three line setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setTitle("Main Page"); }
add one line toolbar.setTitle("Main Page")
In your activity override this method.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
This will inflate your menu below:
<?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/menu_main_setting"
android:icon="#drawable/ic_settings"
android:orderInCategory="100"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
<item
android:id="#+id/menu_main_setting2"
android:icon="#drawable/ic_settings"
android:orderInCategory="200"
app:showAsAction="always"
android:actionLayout="#layout/toolbar"
android:title="Setting" />
</menu>
In my case, I'm using an AppBarLayout with a CollapsingToolbarLayout and the menu was always
being scrolled out of the screen, I solved my problem by switching android:actionLayout in menu's XML to
the toolbar's id. I hope it can help people in the same situation!
activity_main.xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.MainScreenActivity"
android:screenOrientation="portrait">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="300dp"
app:elevation="0dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="48dp"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:elevation="0dp"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
main_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/logoutMenu"
android:orderInCategory="100"
android:title="#string/log_out"
app:showAsAction="never"
android:actionLayout="#id/toolbar"/>
<item
android:id="#+id/sortMenu"
android:orderInCategory="100"
android:title="#string/sort"
app:showAsAction="never"/> </menu>
You can achieve this by two methods
Using XML
Using java
Using XML
Add this attribute to toolbar XML
app:menu = "menu_name"
Using java
By overriding onCreateOptionMenu(Menu menu)
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.demo_menu,menu);
return super.onCreateOptionsMenu(menu);
}
}
for more details or implementating click on the menu go through this article
https://bedevelopers.tech/android-toolbar-implementation-using-android-studio/
You don't actually need to touch the fragment/activity class at all to get a menu inside a toolbar. You can use Rohit Singh's method inside onViewCreated method
import androidx.appcompat.widget.Toolbar
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val toolbar = view.findViewById<Toolbar>(R.id.inbox_toolbar)
toolbar.inflateMenu(R.menu.inbox_menu)
}
or
simply define a app:menu element inside the toolbar,
<androidx.appcompat.widget.Toolbar ...
app:menu= "#menu/myMenu" ?>
Simple fix to this was setting showAsAction to always in menu.xml in res/menu
<?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/add_alarm"
android:icon="#drawable/ic_action_name"
android:orderInCategory="100"
android:title="Add"
app:showAsAction="always"
android:visible="true"/>
</menu>
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar;
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_drawer,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_drawer){
drawerLayout.openDrawer(GravityCompat.END);
if (drawerLayout.isDrawerOpen(GravityCompat.END)) {
drawerLayout.closeDrawer(GravityCompat.END);
} else {
drawerLayout.openDrawer(GravityCompat.END);
}
}
return super.onOptionsItemSelected(item);
}
res/layout/drawer_menu
<?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/action_drawer"
android:title="#string/app_name"
android:icon="#drawable/ic_menu_black_24dp"
app:showAsAction="always"/>
</menu>
toolbar.xml
<com.google.android.material.appbar.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:titleTextColor="#android:color/white"
app:titleTextAppearance="#style/TextAppearance.Widget.Event.Toolbar.Title">
<TextView
android:id="#+id/toolbar_title"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/app_name"
android:textColor="#android:color/white"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title" />
</androidx.appcompat.widget.Toolbar>
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.my_toolbar);
*// here is where you set it to show on the toolbar*
setSupportActionBar(toolbar);
}
Well, you need to set support action bar setSupportActionBar(); and pass your variable, like so: setSupportActionBar(toolbar);

Categories

Resources