I'm trying to make a filter in a List using ActionBarSherlock's search view. The code I currently have is the following:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getSupportMenuInflater().inflate(R.menu.building_search, menu);
SearchView searchView = new SearchView(getSupportActionBar().getThemedContext());
SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener()
{
public boolean onQueryTextChange(String newText)
{
// this is your adapter that will be filtered
listAdapter.getFilter().filter(newText);
return true;
}
public boolean onQueryTextSubmit(String query)
{
// this is your adapter that will be filtered
listAdapter.getFilter().filter(query);
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
}
return super.onOptionsItemSelected(item);
}
These are my imports:
import android.os.Bundle;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import be.ugent.zeus.hydra.AbstractSherlockActivity;
import be.ugent.zeus.hydra.R;
import be.ugent.zeus.hydra.data.caches.AssociationsCache;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.widget.SearchView;
import com.dd.plist.NSArray;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSString;
import com.dd.plist.XMLPropertyListParser;
import com.emilsjolander.components.stickylistheaders.StickyListHeadersListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
Most of it works: in my actionbar, I get a search icon, which is clickable and expands the searchview. What, however, doesn't work is the actual listener. I've put breakpoints inside both methods, but when I debug, nothing happens. The program doesn't break and nothing gets filtered and I can't figure out why.
Does anyone has any idea?
Thanks in advance.
This is how I implemented my search with ActionBarSherlock:
In the menu.xml under the res/menu folder, I added an icon:
<item android:id="#+id/search"
android:title="#string/search_title"
android:icon="#drawable/ic_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="com.actionbarsherlock.widget.SearchView"/>
I then created a class which is responsible for recieving the action search queries and presenting the data:
public class SearchActivity extends SherlockFragmentActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "This is the search view activity");
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.search_result_layout);
}
private void handleIntent(Intent intent){
if(Intent.ACTION_SEARCH.equals(intent.getAction())){
searcdhQuery = intent.getStringExtra(SearchManager.QUERY);
//here we shall do e search..
Log.d(TAG, "This is the search query:" + searcdhQuery);
//This is the asynctask query to connect to the database...
String[] value = {searcdhQuery};
SearchQuery searchQuery = new SearchQuery();
searchQuery.execute(value);
}
}
#Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
handleIntent(intent);
}
}
In the manifest, this activity is included with Search and View filters as Shown below:
<activity android:name=".SearchActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</activity>
Also in the manifest, don't forget the meta-data in the application showing the default search of the activity, as shown below:
<meta-data android:name="android.app.default_searchable"
android:value=".SearchActivity" />
Finally in the onCreateOptionsMenu, be sure to add the search configuration by associating it with the search service:
//associating the searchable configuration with the search service...
SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView)menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
Nothing is required in the onOptionsItemSelected method.
This worked perfectly for me. In case you need more details please find more information from the Search View Demo in the actionBarSherlock and The developers tutorial on the Setting a Search Interface.
I hope this helps.
In case you haven't found an answer,this is how I'm doing it (I am using ActionBarSherlock):
add an entry to the menu declaration
<item android:id="#+id/menu_search"
android:actionViewClass="com.actionbarsherlock.widget.SearchView"
android:icon="#drawable/wfm_menu_search"
android:showAsAction="always|withText|collapseActionView"
android:title="#string/menu_search"/>
In your activity override"onCreateOptionsMenu" to inflate your menu and associate your SearcView :
public boolean onCreateOptionsMenu(final Menu menu) {
getSupportMenuInflater().inflate(R.menu.main_menu, menu);
this.refreshMenuItem = menu.findItem(R.id.menu_refresh);
this.searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
this.searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// collapse the view ?
menu.findItem(R.id.menu_search).collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// search goes here !!
// listAdapter.getFilter().filter(query);
return false;
}
});
That's it, no other activities. Hope you find it useful.
Is that your full code? Right now in the onCreateOptionsMenu you create a SearchView and assign to it a OnQueryTextListener but that is all you do with it. I don't see in your code where you add this SearchView to the inflated menu.
As you say you see the widget on the screen, I'm assuming you have declared the widget in the R.menu.building_search file, in which case you should look for that widget(which doesn't have a listener set on it so no action is performed) and not declare a new one(which will not interact with the user):
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
(This is from the Search guide on the android developer site, if I'm not mistaken this should work for ActionBarSherlock as well).
As every other answer contained a bit of truth, but didn't answer the question fully, I'll create my own answer.
When this issue was created - half a year ago - ABS did not fully implement the SearchView functionality. As of ABS 4.2.0, this has been implemented.
My full implementation, by following the ABS sample app, can be found here.
Related
I am trying to create an Android app with a search button in the Action Bar and when the user presses on the search button, then a search text box appears on the action bar, like in Google's Messenger app (see below).
I tried to implement it as shown below but my app looks like this:
There are a few problems with this. For example, the text reads "Search..." with the elipsis, unlike a simple "Search" without the elipsis, but by far the most concerning thing, is that there is no back button in the toolbar, the search button is pushed too far to the left, and the overflow button on the right has been pushed to the side. In addition, pressing the physical back button on my device does not collapse the searchview, it just exists to app.
Some of the code which I used to try to implement the search bar is below. I tried to set a SearchViewExpandListener as seen below so that the back button would appear when the search view is expanded, however it does not work.
EDIT: I also ran the app with breakpoints on my onMenuItemActionExpand and onMenuItemActionCollapsed methods, and I found out that these methods are in fact never called.
MainActivity.java
import android.content.Context;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
// See above
MenuItemCompat.setOnActionExpandListener(searchItem, new SearchViewExpandListener(this));
MenuItemCompat.setActionView(searchItem, searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
Toast.makeText(MainActivity.this, "You searched " + s, Toast.LENGTH_SHORT).show();
return false;
}
#Override
public boolean onQueryTextChange(String s) {
return false;
}
});
return true;
}
// See above
private class SearchViewExpandListener implements MenuItemCompat.OnActionExpandListener {
private Context context;
public SearchViewExpandListener (Context c) {
context = c;
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
((AppCompatActivity) context).getSupportActionBar().setDisplayShowHomeEnabled(true);
return false;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
((AppCompatActivity) context).getSupportActionBar().setDisplayShowHomeEnabled(false);
return false;
}
}
}
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/action_search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"/>
<item android:id="#+id/action_about"
android:title="About"
app:showAsAction="never"/>
</menu>
It also appears that it is not just me who has this problem. This guide on implementing a SearchView appears to experience similar issues.
So what is the correct way to implement a search bar in an AppCompatActivity which results in a search bar like that in Google's Material Design guidelines and like that in their apps such as Google Messenger? I feel like I've been Googling endlessly for the past while, but I cannot find anything which helps me.
Use collapseActionView flag along with always in showAsAction on serchView menu item
app:showAsAction="always|collapseActionView"
The collapseActionView flag indicates how to display the widget when the user is not interacting with it: If the widget is on the app bar, the app should display the widget as an icon. If the widget is in the overflow menu, the app should display the widget as a menu item. When the user interacts with the action view, it expands to fill the app bar.
I have an activity with the new Toolbar. In this toolbar i have only one icon... my SearchView icon. When i click on that icon it opens an EditText in the Toolbar and im able to write what im looking for. The problem is that when i click on Search icon, the content of my Activity (FrameLayout with fragment) is reloaded.
EDIT:
plus: when click on icon, it reloads the activity and open EditText, after that the Activity SearchResult is called, and if i press the back button in that activity i return to the MainActivity and the searchview is still opened.
How to prevent that?
Thats my Manifest part of search (MainActivity has the icon):
<meta-data
android:name="android.app.default_searchable"
android:value=".activity.SearchResult_" />
<activity
android:name=".activity.MainActivity_"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:screenOrientation="portrait" >
</activity>
<activity
android:name=".activity.SearchResult_"
android:label="#string/title_activity_search_result"
android:screenOrientation="portrait" >
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
Thast my OnCreateOptionsMenu:
#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);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener()
{
public boolean onQueryTextChange(String newText)
{
Log.d("Query", newText);
return true;
}
public boolean onQueryTextSubmit(String query)
{
Log.d("Search", query);
SearchResult_.intent(MainActivity.this).extra("query", query).start();
return true;
}
};
SearchView searchView = null;
if (searchItem != null) {
searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
}
return super.onCreateOptionsMenu(menu);
}
I know I am late to the thread, but here is the proper solution. The way the SearchView default behavior works is that it will automatically send an ACTION.SEARCH intent to the searchable activity declared in your manifest. Upon sending, it will create a new instance of that activity, so that the onCreate() method can be called and the intent can be handled.
In order to work around this behavior, simply declare the launchMode for the searchable activity as 'SingleTop'. android:launchMode="singleTop"
According to Android documentation for "singleTop"
(https://developer.android.com/guide/components/activities/tasks-and-back-stack):
"If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity." If you declare your searchable activity as 'singleTop', make sure you override onNewIntent() and handle the ACTION.SEARCH intent data accordingly.
In your onQueryTextSubmit method do:
searchView.setQuery (query, false);
You cant. unfortunately everyone has the same exact issue. searchViews always call the query when it is opened. no way to avoid it. I have seen some people have a boolean called first and set it to true. then only do logic if it is false. then on the first query call set it to false. not a good way but it should work
I don't know if that it is a bad practice, but I fix it like this:
#Override
protected void onResume() {
super.onResume();
if (searchView != null) {
if (searchView.getQuery().length() <= 0) {
searchView.setQuery("", false);
}
}
}
I have implemented search function using SearchManager and SearchView in the action bar. The same activity that shows the search view performs the search and shows the search result. This is working fine, and I can get the search query from the onNewIntent() without a problem.
When the user clicks the back button to get out of the search mode, I need to redisplay all items. How do I accomplish this? I tried intercepting OnDismiss and OnCancel of the search manager as well as the OnClose of the search view. Nothing ever gets called. Code below:
#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);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
//Try to detect end of search session. None of the listeners getting called.
searchManager.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel() {//...}
});
searchManager.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss() {//...}
});
searchView.setOnCloseListener(new OnCloseListener() {
#Override
public boolean onClose() {
return false;
}
});
return true;
}
The manifest file entry for the activity is like this:
<activity
android:name="com.example.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop">
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I was facing the same problem, and I found the solution which is quite simple. If you are using the searchWidget (like me) you simply need to do this:
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
#Override
public boolean onClose() {
// Put your code here to clear and display the results
return false;
}
});
Because actually what are the user is closing is the SearchView, not the SearchManager. I've just test it and it works like a charm!
Hope this works for you.
Regards
I have one Activity with a fragment to list some data. I've already implemented the search using the SearchView (the nice looking search field on action bar).
The search is working fine, user input the data, press the search button and the results are filtered as expected.
My problem is that I can't "reset" the search back to all results. I already tried setting the Dismiss and Cancel listenners on the searchManager object but the onDismiss and oncancel methods are never being called.
Here is my action on the manifest:
<activity
android:name=".ClientesActivity"
android:label="#string/title_activity_clientes"
android:parentActivityName=".MenuPrincipalActivity"
android:launchMode="singleTop" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="MenuPrincipalActivity" />
<meta-data android:name="android.app.searchable"
android:resource="#xml/cliente_searchable" />
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
The methods on the ClientesActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
clientesService = new ClientesService(getBaseContext());
setContentView(R.layout.activity_clientes);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, ClienteFragment.newInstance(), ClienteFragment.class.getSimpleName())
.commit();
}
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if(Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
clientesService.findByNameLike(query);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.clientes, menu);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
searchView.setSubmitButtonEnabled(true);
return true;
}
It's not showing the Listenners because I rolled back the changes after nothing worked.
But basically o added the listenners before the 'return true' on the onCreateOptionsMenu method.
It was nothing fancy at first, just annonymous class overriding the interface with onDismiss method implemented, tried to put some logs there and the method was never called.
Take a look at android.widget.SearchView#setOnQueryTextFocusChangeListener. As far as I can tell the hasFocus will be true when the searchview is displayed and will not be called again with false until the user hits the upstack/back arrow to close the search. Oddly, I never see android.widget.SearchView#setOnCloseListener called
Alternately, implement an onOptionsItemSelected and call android.app.Activity#onSearchRequested() to trigger the search dialog in order to have those registered callback methods utilized.
#Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();//delegate upstream
break;
default:
return super.onOptionsItemSelected(item);
}
}
It's not very clear in the Invoking the search dialog documentation. I don't see it declared in the documentation. But it seems if you use just the search widget, the SearchManager callbacks are not triggered.
I am trying to implement a ShareActionProvider using the support library in a contextual action bar in my fragment. I face no issues implementing it in a normal action bar( onCreateOptionsMenu() ), but when i try it in the CAB ( onCreateActionMode() in MultiModeListener interface), I get the error :
getActionProvider: item does not implement SupportMenuItem; returning null
Looking at the Android source at https://cells-source.cs.columbia.edu/plugins/gitiles/platform/frameworks/support/+/30837f1095c803f332f4a1c3f0917c8afdd50156/v4/java/android/support/v4/view/MenuItemCompat.java, the problem seems to be because my MenuItem is not an instance of SupportMenuItem :
public static ActionProvider getActionProvider(MenuItem item) {
if (item instanceof SupportMenuItem) {
return ((SupportMenuItem) item).getSupportActionProvider();
}
// TODO Wrap the framework ActionProvider and return it
Log.w(TAG, "getActionProvider: item does not implement SupportMenuItem; returning null");
return null;
}
Any ideas on how i can go about resolving this ?
Manifest :
<activity
android:name=".myactivity_ActionBarActivity"
android:theme="#style/Theme.AppCompat.Light"
android:windowSoftInputMode="stateUnchanged">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Activity :
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
public class myactivity_ActionBarActivity extends ActionBarActivity{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.actionbaractivity_layout); //loads a fragment
}
}
fragment :
import android.support.v7.widget.ShareActionProvider;
import android.support.v4.view.MenuItemCompat;
import android.view.MenuItem;
import android.view.Menu;
import android.support.v4.app.Fragment;
...
...
#Override
public void onActivityCreated(Bundle savedInstanceState) {
...
...
//Handle Action mode events
myListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
private ShareActionProvider mShareActonProvider;
....
....
#Override
public boolean onCreateActionMode(ActionMode mode,
Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.chatsession_contextmenu, menu);
//get the ShareActionProvider from the menu item
MenuItem item = menu.findItem(R.id.share_menu);
mShareActonProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(item);
return true;
}
}
...
...
}
Menu layout file :
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/delete_menu"
android:title="Delete message"
myapp:showAsAction="ifRoom|withText"
android:icon="#drawable/ic_action_discard">
</item>
<item
android:id="#+id/share_menu"
android:title="Share message"
myapp:showAsAction="ifRoom|withText"
android:icon="#drawable/ic_action_share"
myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider">
</item>
</menu>
Edit 1 :
The root of the problem seems to be the difference in the Menu object that is being passed as argument to onCreateActionMode(ActionMode mode, Menu menu) and onCreateOptionsMenu(Menu menu, MenuInflater inflater). Only the one in onCreateOptionsMenu has the MenuWrapperICS. Here is a screenshot of both objects in debug mode :
onCreateActionMode(ActionMode mode, Menu menu) :
onCreateOptionsMenu(Menu menu, MenuInflater inflater) :
The problem is that the MultipleModeListener interface extends the android.view.ActionMode.Callback, as can be seen in the source code at http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#6301. If you are using ShareActionProvider from the support library, you need the android.support.v7.view.ActionMode.Callback instead.
The solution is to create your own ActionMode.CallBack implementation instead of using the framework's MultipleModeListener. This way you make sure that the support libraries are being used wherever required.
For example :
Import the v7 version of ActionMode and ActionBarActivity in your fragment
import android.support.v7.view.ActionMode;
import android.support.v7.app.ActionBarActivity;
Create an onClickListener for your list view and use startSupportActionMode to start your custom ActionMode.CallBack implementation
myListView.setItemsCanFocus(false);
myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
actionMode = null;
myListView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
if(myListView.getCheckedItemCount() == 0){
actionMode.finish();
return;
}
if(actionMode == null){
actionMode = ((ActionBarActivity)getActivity()).startSupportActionMode(new ContextualActionBar());
}
}
});
Create your custom ActionMode.Callback implementation
private class ContextualActionBar implements ActionMode.Callback{
private ShareActionProvider mShareActionProvider;
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch(item.getItemId()){
case R.id.share_menu :
mode.finish();
return true;
default :
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.chatsession_contextmenu, menu);
//Initialize the ShareActionProvider
MenuItem shareMenuItem = menu.findItem(R.id.share_menu);
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareMenuItem);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "test message");
mShareActionProvider.setShareIntent(shareIntent);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
//Nullify the actionMode object
//so that the onClickListener can identify whether the ActionMode is ON
actionMode = null;
//Uncheck all checked messages
SparseBooleanArray selectedItems = myListView.getCheckedItemPositions();
for(int i=0;i<selectedItems.size();i++){
myListView.setItemChecked(selectedItems.keyAt(i), false);
}
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO Auto-generated method stub
return false;
}
}
Be careful to use the right MenuInflater when populating the IMenu in onCreateActionMode. When I use the one from the mode object, as you do in your fragment class, it doesn't create the support version of ShareActionProvider. I switched to using the MenuInflater from the parent AppCompatActivity class and it worked fine.
Given that the mode object is from the support library, one would assume it would use the support inflater, but apparently not.
Are you sure that your activity extends ActionBarActivity?
I had an almost identical setup. The problem in my case was that Proguard was optimizing away the constructor of the ShareActionProvider. There is a bug that they while they do keep the class and methods of ActionProvider classes detected in your XML, they don't keep the constructors or the class name.
If you have a "Cannot instantiate class" warning in your log, then this would apply to you, too.
Here is the Android bug report that helped me.
And the proguard config I added was:
-keepnames public class * extends android.support.v4.view.ActionProvider
-keepclassmembers public class * extends android.support.v4.view.ActionProvider {
<init>(android.content.Context);
}