I have an AutoCompleteTextView as Collabsible ActionItem, and i want the keyboard to be displayed when it gets expanded and focussed. This is my code in onCreateOptionsMenu():
menu.add("Search")
.setIcon(R.drawable.ic_search)
.setActionView(R.layout.collapsible_edittext)
.setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS
| MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
final MenuItem searchMenuItem = menu.getItem(0);
searchMenuItem.setOnActionExpandListener(new OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView) item
.getActionView();
autoCompleteTextView
.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
Log.d(TAG, "onFocusChange: " + hasFocus);
if (hasFocus) {
mInputManager.showSoftInput(v,
InputMethodManager.SHOW_FORCED);
} else {
mInputManager.hideSoftInputFromWindow(
v.getWindowToken(), 0);
}
}
});
autoCompleteTextView.requestFocus();
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView) item
.getActionView();
autoCompleteTextView.clearFocus();
autoCompleteTextView.setText("");
return true;
}
});
When I click on the ActionItem the first time, no keybord is shown. After collapsing and then clickin on the Item the keyboard gets shown. But I want the keyboard to be shown the first time the user clicks on the action item.
I'm using ActionBarSherlock if that matters.
So why is the keyboard not shown on first expansion? Any ideas?
Have you tried manually setting the focus to the edit text and manually showing the keyboard in the onOptionsItemSelected method?
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_SEARCH:
// select edittext here
// show keyboard here
return true;
}
return super.onOptionsItemSelected(item);
}
EDIT: I found this code to show the keyboard from here:
https://code.google.com/p/android-batavierenrace/source/browse/trunk/BataApp/src/com/ut/bataapp/activities/TeamsActivity.java
I tested it on my app and it works...
public static void setKeyboardFocus(final EditText primaryTextField) {
(new Handler()).postDelayed(new Runnable() {
public void run() {
primaryTextField.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
primaryTextField.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , 0, 0, 0));
}
}, 100);
}
Related
Is it possible to focus the List View Items through any button click?
Like i want that when user click on Floating Action Button then the listview gets focused. I dont want to show checkbox type layout on button clicked. I just want to show the same like in the screenshot on Button click.
What i did is I put the listview onItemLongClick code in the button click blocks but it doesnot work.
fabButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
listViewMessages.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listViewMessages.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
tv.setText(listViewMessages.getCheckedItemCount()+ " Selected");
}
#Override
public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu:
}
});
mode.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contextual, menu);
fabButton.setVisibility(View.INVISIBLE);
fabButtonn.setVisibility(View.VISIBLE);
fabButtonn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
for ( int i=0; i< messageListAdapter.getCount(); i++ ) {
listViewMessages.setItemChecked(i, true);
}
}
});
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
fabButton.setVisibility(View.VISIBLE);
fabButtonn.setVisibility(View.GONE);
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an invalidate() request
return false;
}
});
With this code if user clcik on button then he/she has too long press items again to focus the list items which is not what i want. I want to focus items right when button click. Any explanation or link provided will be helpful
When using search view, I have a requirement from customer that they want to retain the search content after reopen the search view. My Search view is on a list view and do a real timing filtering based on what user input into the search box. When closed the search box by either click the back button on the phone or click the soft back button on the top left on action bar, the search box closed, search view iconfied. But when reopen it next time, the search query used last time is also been cleared, which I do not want.
My question is that is there a way I can keep the search view content there. Just hiding the search box, but not clear the content?
My related code are as follow:
MenuItem search;
SearchView searchView;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_locationlist_fragment, menu);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
search = menu.findItem(R.id.action_search_location_list);
searchView = (SearchView) MenuItemCompat.getActionView(search);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setOnQueryTextListener(this);
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
//This will make sure, when user closed search view, the list will be restored.
if(!hasFocus) {
Log.i(Tags.LOCATIONLIST,"Search Close");
search.collapseActionView();
} else {
}
}
}
});
ImageView closeButton = (ImageView)searchView.findViewById(R.id.search_close_btn);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText searchEditText = (EditText)searchView.findViewById(R.id.search_src_text);
searchEditText.setText("");
if (((LocationListAdapter)locationListView.getAdapter())!=null) {
((LocationListAdapter) locationListView.getAdapter()).getFilter().filter("");
}
}
});
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search_location_list:
((BaseActivity) getActivity()).onSearchRequested();
return true;
case R.id.action_refresh_location_list:
refreshLocationList();
return true;
default:
return false;
}
}
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
if (((LocationListAdapter)locationListView.getAdapter())!=null) {
if (TextUtils.isEmpty(s)) {
locationListView.clearTextFilter();
} else {
((LocationListAdapter) locationListView.getAdapter()).getFilter().filter(s);
//locationListView.setFilterText(s.toString());
}
}
return true;
}
Use
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setIconified(false);
Any query text is cleared when iconified. So setIconified to false. And i have used android.widget.SearchView
Save your String in a variable (e.g. myWantedString) and
override setOnClickListener that trigers everytime you open the SearchView and use setQuery. Your code should be:
searchView.setOnSearchClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
searchView.setQuery(myWantedString, false);
}
});
To save your string each time the SearchView closes implement setOnCloseListener and override onClose():
searchView.setOnCloseListener(new SearchView.OnCloseListener()
{
#Override
public boolean onClose()
{
myWantedString = searchView.getQuery();
return false;
}
});
searchView.setQuery() works if was called with a delay after menu item expansion.
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
// set query text with a delay
searchView.post(new Runnable() {
#Override
public void run() {
searchView.setQuery(query, false);
}
});
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
});
You can create an Activity which can be called when the user searches and the search result can be stored in the Bundle during the callback method onPause or onSaveInstanceState , when the Activity is called once again restore it from the bundle.
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setIconified(false);
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
searchView.setQuery("SEARCH_WORD", false);
}
});
https://developer.android.com/reference/android/widget/SearchView
Sets a listener to inform when the search button is pressed. This is only relevant when the text field is not visible by default. Calling setIconified(false) can also cause this listener to be informed.
I have a search view as an action item. Every thing is working fine except that I want to intercept the search executed event. At that time a new activity is started with search results. When that happens I want to collaps the search view in the previous activity. So when user comes back out of the search result activity, the action menu should be collapsed.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//Used to put dark icons on light action bar
//Create the search view
final SearchView searchView = new SearchView(getSupportActionBar().getThemedContext());
searchView.setQueryHint("Search");
menu.add(Menu.NONE,Menu.NONE,1,"Search")
.setIcon(R.drawable.abs__ic_search)
.setActionView(searchView)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
if (newText.length() > 0) {
// Search
} else {
// Do something when there's no input
}
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
Toast.makeText(getBaseContext(), "dummy Search", Toast.LENGTH_SHORT).show();
setSupportProgressBarIndeterminateVisibility(true);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
setSupportProgressBarIndeterminateVisibility(false);
}
}, 2000);
return false; }
});
return true;
}
I think you can collapse SearchView in onQueryTextSubmit method, see above code
With this code (taken from ABS examples) I'm able to add a "Search" icon in my ActionBar which will display an EditText when clicked (to search in a list):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, searchId, Menu.NONE, R.string.menu_search)
.setIcon(android.R.drawable.ic_menu_search)
.setActionView(R.layout.collapsible_edittext)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
return true;
}
With this code I'm able to show a different layout after tapping the "Search" icon:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case searchId:
search = (EditText) item.getActionView();
search.addTextChangedListener(filterTextWatcher);
search.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
setContentView(R.layout.search);
this.allSongs = data.getSongs();
ListView list = (ListView) findViewById(R.id.songList);
list.setAdapter(new SongAdapter(this, this.allSongs));
}
return true;
}
With this code I'm able to handle my search:
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
List<Song> results = new ArrayList<Song>();
Locale locale = Locale.getDefault();
for (Song song : allSongs) {
if (song.getTitle().toLowerCase(locale).contains(s.toString().toLowerCase(locale)))
results.add(song);
}
ListView list = (ListView) findViewById(R.id.songList);
list.setAdapter(new SongAdapter(ctx, results));
}
};
When the user taps the "Search" icon, the EditText appears in ActionBar and the App Icon gains the "back" left arrow.
If the user taps "Back" button or taps the ActionBar icon (with left arrow), the EditText disappears.
I'd like to intercept this event (no, onOptionsItemSelected() doesn't fire this time) and show the previous layout, in addition to hiding the EditText.
Note: I need API8 (Android 2.2) compatibility!
Thank you!
When using an ActionView, tapping "up" or "back" doesn't result in an Ancestral Navigation (which can be handled by onOptionsItemSelected) but results in a Collapsible Action event.
Found here on Android Developers.
Handling collapsible action views
If you need to update your activity based on the visibility of your
action view, you can receive callbacks when it's expanded and
collapsed by defining an OnActionExpandListener and registering it
with setOnActionExpandListener(). For example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options, menu);
MenuItem menuItem = menu.findItem(R.id.actionItem);
...
menuItem.setOnActionExpandListener(new OnActionExpandListener() {
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
return true; // Return true to collapse action view
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true; // Return true to expand action view
}
});
}
So, to answer to my question, I was searching for onMenuItemActionCollapse event.
PS: for better consistency I should move my case searchId: from onOptionsItemSelected to onMenuItemActionExpand
For the Home button, can I assume that you called
mActionBar.setHomeButtonEnabled(true);
when setting up the Sherlock Action Bar in onCreate()? I believe that's required in order to get onOptionsItemSelected() callbacks with an item ID of android.R.id.home when the home button is clicked.
For the back button, I think you just need to override onKeyDown in your activity:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
// Do something
return true;
}
return super.onKeyDown(keyCode, event);
}
I am currently using an ActionBar menu item to display a SearchView in the action bar. When the search menu item is expanded the soft keyboard is displayed which is what I want. Now, when the user presses the back button to close the soft keyboard, I would also like to collapse the SearchView in the action bar.
I have tried implementing the following listeners OnKeyListener and OnFocusChangeListener on the MenuItem and the ActionView. I have also tried using OnBackPressed() in the Activity. None of the above detect when the back button is used to close the soft keyboard.
Any ideas?
I have implemented OnActionExpandListener to know when the SearchView is visible.
I'll expand on #user1258568 's answer for the lazy. This worked for me. Note that it clears your query when focus is lost.
final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean queryTextFocused) {
if(!queryTextFocused) {
searchMenuItem.collapseActionView();
searchView.setQuery("", false);
}
}
});
I found a better solution.
searchView.setOnQueryTextFocusChangeListener().
The OnQueryTextFocusChangeListener gets called when the keyboard is displayed or hidden. Gets called first when the keyboard is displayed and the search view will have focus. Gets called again when keyboard is hidden and search view will lose focus, can close search viewthen using
menuItem.collapseActionView().
Just Override onBackPressed like this:
#Override
public void onBackPressed() {
if (searchView.isShown()){
searchView.onActionViewCollapsed(); //collapse your ActionView
searchView.setQuery("",false); //clears your query without submit
isClosed = true; //needed to handle closed by back
} else{
super.onBackPressed();
}
}
and your onCreateOptionsMenu would inflate the mSearchView like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_search, menu);
mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnSearchClickListener(this);
mSearchView.setOnCloseListener(this);
isClosed = true;
return true;
}
have you class implement the following like this:
public class myActivity extends FragmentActivity implements
SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {
which you will also need:
#Override
public void onClick(View view) {
isClosed = false;
}
#Override
public boolean onClose() {
isClosed = true;
return false;
}
You will need to make "mSearchView" and "isClosed" both global variables to the activity.
The answer from Jon Willis works great. This is an improvement to his answer.
First, create a new class that implements View.OnFocusChangeListener:
public class SearchViewFocusListener implements View.OnFocusChangeListener {
private final MenuItem mMenuItem;
public SearchViewFocusListener(MenuItem menuItem) {
mMenuItem = menuItem;
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
mMenuItem.collapseActionView();
if (v instanceof SearchView) {
((SearchView) v).setQuery("", false);
}
}
}
}
Next, set the listener on your SearchView:
searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));
You only need to put the "collapseActionView" attribute in the menu layout
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/menu_item_search"
android:title="#string/search"
android:iconifiedByDefault="true"
android:icon="#drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>
That will give you the functionality you look for all by itself.Don't forget to call the method "clearFocus" on the SearchView to close the keyboard once you send the query.
This is what I did for making the keyboard disappear. You can try to see if this works for you. I set the searchView to invisible and then to visible again.
//set query change listener
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure keyboard disappears when query is submitted
*/
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
return false;
}
});
It's achievable like this:
private void setupSearchView(Menu menu) {
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
[...]
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchMenuItem.collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}
Solutions based on setOnQueryTextFocusChangeListener() did not work for me because the event was not launched - the searchView did not lose focus when submitted, probably because I perform the search in the same activity that contains the Search View.
Anyway, I think using OnQueryTextListener is more correct, as it describes the event of submitting text more precisely.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.home_screen, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
final SearchView searchView = (SearchView) searchMenuItem
.getActionView();
searchView.setIconifiedByDefault(false);
if (searchManager != null && searchView != null) {
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView
.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
if (searchMenuItem != null) {
searchMenuItem.collapseActionView();
}// end if
if (searchView != null) {
searchView.setQuery("", false);
}// end if
}// end if
}
});
searchView
.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure
* keyboard disappears when query is submitted
*/
if (searchView != null) {
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
}
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
If you want to collapse keyboard when user clicks search icon on keyboard
this can be achieved by simple
inside onquerytextsubmitted {
searchView.clearfocus()
}
You need to call setIconified twice.
To actually collapse your search view and close the keyboard.
With first call text of search view is cleared with second call keyboard and search view get closed.
For some reason, menuItem.collapseActionView() did not work so I used searchView.setIconified(true) instead.
This gives the below result as the code sample.
final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
searchView.setIconified(true);
}
}
});