I have an activity with an ActionBar. One of the options is to search a document (not necessarily local). I want to use a contextual action bar (CAB) with the following items:
I want to use a CAB for several reasons. Primarily, I want the user to pick an option which will bring up the CAB defined above. When the user is done with the search, they select the done button and the ActionBar returns to previous state.
Here's the problem. I can't get the search item to appear in my CAB in an expanded state. NOTE: The activity I'm attempting to modify is NOT the main activity but is an activity launched by the user based on certain events. Once this activity is loaded, the user may or may not decide to use the 'search' functionality I'm describing. I also do not want Android to do the searching. I have an API that will search for the results I want and allow me to navigate to the prev/next search result.
My code for the CAB (which is being called correctly) is:
protected ActionMode mActionModeSearch;
private ActionMode.Callback mActionModeSearchCallback = new ActionMode.Callback()
{
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu)
{
actionMode.getMenuInflater().inflate(R.menu.pdf_menu_search, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.pdf_menu_search_item).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
@Override
public boolean onQueryTextSubmit(String s)
{
return false;
}
@Override
public boolean onQueryTextChange(String s)
{
return false;
}
});
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu)
{
return false;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem)
{
switch(menuItem.getItemId())
{
case R.id.pdf_menu_search_prev:
findPrevSearchResult();
return true;
case R.id.pdf_menu_search_next:
findNextSearchResult();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode actionMode)
{
//resetHideToolbarsTimer();
}
};
The CAB menu code is:
<?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">
<group android:id="@+id/group_search_mode">
<item
android:id="@+id/pdf_menu_search_item"
android:title="@string/search"
android:icon="@drawable/ic_pdf_action_search"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView"/>
<item
android:id="@+id/pdf_menu_search_prev"
android:title="@string/search_prev"
android:icon="@drawable/ic_pdf_action_search_prev"
app:showAsAction="ifRoom" />
<item
android:id="@+id/pdf_menu_search_next"
android:title="@string/search_next"
android:icon="@drawable/ic_pdf_action_search_next"
app:showAsAction="ifRoom" />
</group>
I also changed my activity definition in AndroidManifest.xml although I'm not sure this is required:
<activity
android:name="com.myapp.myActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.default_searchable"
android:value="com.myapp.myActivity" />
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
When I run the app, the activity load correctly. When the user selects the search option, I load the CAB and it seems to be running fine. I've stepped through the code to make sure the onCreateActionMode is functioning as expected. But, all I see is the icon for search, next and previous, with the 'Done' button. When I touch the 'Search' icon, it doesn't do anything. No text field is created in the CAB for me to enter text. What am I doing wrong????
Screenshot showing the CAB coming up. As you can see, the search icon shows but doesn't do anything when I press it. What I really need is for the search edit box to appear by default.
First, we should set always
value for app:showAsAction
of all menu items:
<?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">
<group android:id="@+id/group_search_mode">
<item
android:id="@+id/pdf_menu_search_item"
android:icon="@drawable/ic_pdf_action_search"
android:title="@string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
<item
android:id="@+id/pdf_menu_search_prev"
android:icon="@drawable/ic_pdf_action_search_prev"
android:title="@string/search_prev"
app:showAsAction="always"/>
<item
android:id="@+id/pdf_menu_search_next"
android:icon="@drawable/ic_pdf_action_search_next"
android:title="@string/search_next"
app:showAsAction="always"/>
</group>
</menu>
Secondary, in this case we don't need to set intent filter for our Activity
and searchable info for our SearchView
.
Definition of this Activity in AndroidManifest.xml
:
<activity
android:name="com.myapp.myActivity"
android:label="@string/app_name" />
ActionMode.Callback
implementation:
private ActionMode.Callback mActionModeSearchCallback = new ActionMode.Callback() {
private SearchView mSearchView;
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
actionMode.getMenuInflater().inflate(R.menu.home, menu);
mSearchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.pdf_menu_search_item));
mSearchView.setIconifiedByDefault(false);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
return false;
}
});
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
mSearchView.requestFocus();
return true;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.pdf_menu_search_prev:
findPrevSearchResult();
return true;
case R.id.pdf_menu_search_next:
findNextSearchResult();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
}
};
I just tried this code on three 4.0+ devices and it was fully working. But I didn't test on devises with lower OS versions.
Hope it will be helpful for you.
i have problem searchView in CAB so i set layout(with edittext) in manu item, it give me same view as searchview try this i hope it works for you
menu/search.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/edt_mySearch"
android:actionLayout="@layout/search_bar"
android:enabled="true"
android:showAsAction="always"
android:visible="true"/>
</menu>
layout/search _bar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:layout_alignParentLeft="true"
android:id="@+id/edt_search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint=" Search..."
/>
</RelativeLayout>
and myAction mode
mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// mode.setTitle("Demo");
getSupportMenuInflater().inflate(R.menu.search, menu);
RelativeLayout m = (RelativeLayout) menu.findItem(
R.id.edt_mySearch).getActionView();
EditText mSearchView = (EditText) m
.findViewById(R.id.edt_search);
mSearchView.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
// search here
}
});
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With