I'm a newbie on programing specially with android.
I use a SearchView in my app but I don't know how block special character.
I have seen topics about EditText but nothing about SearchView and I need help.
I use SearchView in App bar with this xml for menu :
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search"
android:icon="#drawable/ic_search_white_24dp"
android:title="#string/search_title"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
</menu>
and this Activity code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_results);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_option_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
So I waiting your answers, thanks.
You can detect when a char is entered:
//In onCreate
EditText et;//initialize
et.addTextChangedListener(tw);
outside onCreate:
private TextWatcher tw = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//If the text contains a "bad" char, (char that isn't equal to A-Z/a-z or 0-9, remove it from the edittext
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
};
(the edittext should be declared as a class variable)
Suggestion as to detection:
//s is the char sequence
String string = s.toString();
boolean found = false;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++){
String ch = s.charAt(i) + "";//Convert to check with regex
if(!Pattern.compile("[A-Z|a-z|0-9]").matcher(ch).find()){
found = true;
}else{
sb.append(ch);
}
}
if(found){
editText.setText(sb.toString());//only apply the text if a special char is found
}
My interpretation of special char was non-numeric and non-A-Z. This can be modified to match any char you count as special. If there is a few chars you want to disallow, it is better to check for those chars instead of checking if it contains all the others.
I've had this issue with '>' being converted to '|>'. This is how I fixed it with Kotlin:
override fun onQueryTextChange(newText: String?): Boolean {
Log.w(TAG, "new text $newText")
if (newText != null && newText.contains("|>")) {
val text = newText?.replace("|>", ">")
search.setQuery(text, false)
} else {
// do something
}
return false
}
Related
I want to add a search icon in the EditText hint.
Actually, I am using EditText same as SearchView for that I want to set a search icon in between the EditText which disappear when user write something into the EditText same as hint text disappear
Please check the below screenshot:
In xml add to your EditText: android:drwableLeft="#drawable/imageSearch"
That puts an image in your EditText, but its still there after you type text in.
To make image disappears, just override in your activity:
#Override
public void afterTextChanged(Editable editable) {
if(editable.toString().length() > 0) {
searchEditText.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
} else {
searchEditText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.image, 0, 0, 0);
}
}
That should do the trick
Set drawableLeft to your edittext like
android:drawableLeft="#drawable/fi_search"
and hide it when some text typed in your editText and visible it when nothing is entered in it
like
csSearchTxt.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.length() == 0) {
csSearchTxt.setCompoundDrawablesWithIntrinsicBounds(R.drawable.fi_search, 0, 0, 0);
}
else
{
csSearchTxt.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
Please use Spannable string and ImageSpan to add icon as hint in edittext
ImageSpan imageHint = new ImageSpan(this, R.drawable.ic_search_accent_24dp);
String blankString = " ";
SpannableString spannableString = new SpannableString(blankString);
spannableString.setSpan(imageHint, 0, blankString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
searchEdit.setHint(spannableString);
Create 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/menu_search_album"
android:icon="#drawable/ic_search"
android:title="#string/str_search_album"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|always" />
</menu>
To add hint Just use hint attribute in to your menu
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_label"
android:hint="#string/search_hint" >
for more read this bolg
in Menifest.xml
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
For more information how to Creating a Search Interface
in jave
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_photos_activity, menu);
final MenuItem item = menu.findItem(R.id.menu_search_photos);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
List<MyAlbumItemPojo.DataFields> filteredModelList = filter(arrDataFields, newText);
if (filteredModelList.size() > 0) {
tvDataNotFoundAlbumItem.setVisibility(View.GONE);
return true;
} else {
tvDataNotFoundAlbumItem.setVisibility(View.VISIBLE);
tvDataNotFoundAlbumItem.setText(R.string.str_photo_not_fund);
return false;
}
}
private List<MyAlbumItemPojo.DataFields> filter(List<MyAlbumItemPojo.DataFields> models, String query) {
query = query.toLowerCase();
final List<MyAlbumItemPojo.DataFields> filteredModelList = new ArrayList<>();
for (MyAlbumItemPojo.DataFields model : models) {
final String text = model.getImagename().toLowerCase().toString();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
if (!query.toString().toString().trim().equals("")){
adapter = new MyAlbumAdapter(MyAlbumsActivity.this, (ArrayList<MyAlbumItemPojo.DataFields>) filteredModelList,VisitUserID,VisitUser);
recyclerViewMyAlbums.setAdapter(adapter);
adapter.notifyDataSetChanged();
}else {
adapter = new MyAlbumAdapter(MyAlbumsActivity.this, arrDataFields,VisitUserID,VisitUser);
recyclerViewMyAlbums.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
return filteredModelList;
}
I like to convert on the fly letters from cyrillic to latin. For example when user enter cyrillic letter I like to convert letter to latin. Here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
test = (EditText) findViewById(R.id.test);
InputFilter filter = new InputFilter() {
TransliterationHelper tr = new TransliterationHelper();
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
if (tr.isAlphaCyrilic(source.toString())) {
String convertedString = tr.returnLatinForCyrilic(source.toString());
return convertedString.toUpperCase();
} else if (tr.isAlpha(source.toString()))
return source.toString().toUpperCase();
else
return "";
return null;
}
};
test.setFilters(new InputFilter[]{filter});
}
Here is isAlphaCyrilic function:
public static boolean isAlphaCyrilic(String s) {
boolean isCyrilic = false;
for (char c : s.toCharArray()) {
if (Character.UnicodeBlock.of(c) == Character.UnicodeBlock.CYRILLIC) {
isCyrilic = true;
break;
}
}
return isCyrilic;
}
Here is the code for isAlpha
public static boolean isAlpha(String s) {
String pattern = "^[a-zA-Z ]*$";
if (s.matches(pattern)) {
return true;
}
return false;
}
The function returnLatinForCyrilic, return matched character for cyrillic letter:
public String returnLatinForCyrilic(String s) {
String strTranslated = cyrilicToLatinMap.get(s);
return strTranslated;
}
For example I enter only latin letters or cyrillic letters everything works ok, but when I enter cyrillic letter after latin (I changed keyboard language) method filter called again, and I don't like that.
Does someone has some idea?
I put android:inputType="textNoSuggestions"
so the method filter was not called twice.
I am using Android 4.1.2. I have a SearchView widget on an ActionBar. Documentation on SearchView.OnQueryTextListener from the android developer site states that onQueryTextSubmit is fired/Called when the user submits the query. This could be due to a keypress on the keyboard or due to pressing a submit button."
This does not happen if the search query is empty. I need this to fire on an empty query to clear the search filter of a ListView. Is this a bug or am I doing something wrong?
It is not a bug, the source code deliberately checks against null and empty values:
private void onSubmitQuery() {
CharSequence query = mQueryTextView.getText();
if (query != null && TextUtils.getTrimmedLength(query) > 0) {
However you should be able to use the OnQueryTextChange callback to clear your ListView's filterables when the user clears the search EditText.
I've an easier work around: use onQueryTextChange, but only render if it's empty.
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
renderList(true);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (searchView.getQuery().length() == 0) {
renderList(true);
}
return false;
}
});
I had the same problem and end up with the following solution: custom SearchView + OnQueryTextListener.onQueryTextChange
Custom SearchView:
public class MySearchView extends SearchView {
private boolean expanded;
public MySearchView(Context context) {
super(context);
}
#Override
public void onActionViewExpanded() {
super.onActionViewExpanded();
expanded = true;
}
#Override
public void onActionViewCollapsed() {
super.onActionViewCollapsed();
expanded = false;
}
public boolean isExpanded() {
return expanded;
}
}
Creating action and setting callback:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
searchAction = menu.add(0, SEARCH_ACTION_ID, 0 , getString(R.string.action_search));
searchAction.setShowAsAction(SHOW_AS_ACTION_ALWAYS | SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
searchView = new MySearchView(getSherlockActivity());
searchView.setOnQueryTextListener(searchQueryListener);
searchView.setIconifiedByDefault(true);
searchAction.setActionView(searchView);
}
And last the listener:
private OnQueryTextListener searchQueryListener = new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
search(query);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
if (searchView.isExpanded() && TextUtils.isEmpty(newText)) {
search("");
}
return true;
}
public void search(String query) {
// reset loader, swap cursor, etc.
}
};
Tested on ABS 4.3.
I had same issue with SearchView. My solution which consists of styling SearchView as shown in guide http://novoda.com/blog/styling-the-actionbar-searchview/ and setting OnEditorActionListener for EditText( How do I trigger an action when the user has hit enter?) which is part of the SearchView was this:
final SearchView searchView = (SearchView)findViewById(R.id.search);
int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
EditText searchPlate = (EditText) searchView.findViewById(searchPlateId);
searchPlate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//Do something
}
return false;
}});
It's an old thread but I've found another solution (Kotlin code, but works in Java as well):
override fun onQueryTextChange(newText: String?): Boolean {
if(newText == null || newText.isEmpty())
searchView.setQuery("\u00A0", false)
return true
}
\u00A0 is a character that looks like space, but code-wise it is not. In other words SearchView is not empty. Empty string or " " would not work, because base SearchView uses trim, plus user may want to search text ending or beginning with space. But as far as I know users cannot enter \u00A0 character.
Then all you need to do is override getQuery to return super.getQuery.replace("\u00A0", "") in your custom SearchView
This is a very dirty hack, however it works correctly as expected, enabling the submit action even when there is no text entered (or entered then edited) in the SearchView.
It reflectively gains access to the inner TextView editor action listener, wraps it in a custom listener where it delegates the call to the handler, and finally sets it as the action listener of the inner TextView.
Class klass = searchView.getClass();
try {
Field currentListenerField = klass.getDeclaredField("mOnEditorActionListener");
currentListenerField.setAccessible(true);
TextView.OnEditorActionListener previousListener = (TextView.OnEditorActionListener) currentListenerField.get(searchView);
TextView.OnEditorActionListener newListener = new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (v.getText().length() == 0)
handleQuery("");
return previousListener.onEditorAction(v, actionId, event);
}
};
Field innerTextViewField = klass.getDeclaredField("mSearchSrcTextView");
innerTextViewField.setAccessible(true);
SearchView.SearchAutoComplete innerTextView = (SearchView.SearchAutoComplete) innerTextViewField.get(searchView);
innerTextView.setOnEditorActionListener(newListener);
} catch (Exception e) {
throw new IllegalStateException(e);
}
As others have mentioned this behavior is intentional. I gave up on a solution for OnQueryChangeListener and decided to workaround by implementing OnEditorActionListener on the SearchView's EditText, which you can get a handle to using R.id.search_src_text. As long as you setImeOptions of the SearchView to EditorInfo.IME_ACTION_SEARCH you can handle a click on the keyboard search button. See this SO answer for more details.
I can manage to do it simply by implementing the setOnQueryTextListener in this way:
SearchView searchView = (SearchView) menu.findItem(R.id.searchProductView).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
loadLocalData(newText);
}
return true;
}
});
Where my loadLocalData method is
//query my DB
products = ProductDAO.findByIdList(idList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(layoutManager);
listView.setAdapter(<YOURADAPTER>)
This solution clears your query even if you clear the text with the "X" button
I had the same problem, since empty query's are not supported I had to download and use ActionBarSherlock and then modify the onSubmitQuery() method.
This is how my onSubmitQuery() looks like now
private void onSubmitQuery() {
CharSequence query = mQueryTextView.getText();
if (query == null) {query = "";}
if (mOnQueryChangeListener == null
|| !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
if (mSearchable != null) {
launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString());
setImeVisibility(false);
}
dismissSuggestions();
}
}
Hope this helps.
This is a complete example written in Kotlin:
import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.appcompat.widget.SearchView
/**
* Custom [SearchView] which can listen to empty submit events
*
* If the internal implementation would change, this will not crash at runtime. It will simply
* ignore the empty submit listener and will continue to work as this is the base [SearchView]
*/
class EmptySubmitSearchView #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : SearchView(context, attrs, defStyleAttr) {
private lateinit var searchAutoComplete: SearchAutoComplete
private lateinit var internalEditorListener: TextView.OnEditorActionListener
private var emptySubmitListener: OnEmptySubmitListener? = null
init {
try {
val defaultListenerField = SearchView::class.java
.getDeclaredField("mOnEditorActionListener")
defaultListenerField.isAccessible = true
internalEditorListener = defaultListenerField.get(this) as TextView.OnEditorActionListener
val searchAutoCompleteField = SearchView::class.java
.getDeclaredField("mSearchSrcTextView")
searchAutoCompleteField.isAccessible = true
searchAutoComplete = searchAutoCompleteField.get(this) as SearchAutoComplete
searchAutoComplete.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE && TextUtils.isEmpty(searchAutoComplete.text)) {
emptySubmitListener?.onEmptyTextSubmit()
} else {
internalEditorListener.onEditorAction(v, actionId, event)
}
true
}
} catch (ignored: Exception) {
//Some internal field has changed. Check there is a field called
//mSearchSrcTextView and mOnEditorActionListener and if not update them accordingly
}
}
/**
* Set custom empty listener or null to remove it
*/
fun setOnEmptySubmitListener(listener: OnEmptySubmitListener?) {
emptySubmitListener = listener
}
interface OnEmptySubmitListener {
fun onEmptyTextSubmit()
}
}
You can set a custom listener with setOnEmptySubmitListener which will enable you to distinguish between events.
You can customize the actionId to respond to, in this case I had in my XML the EmptySubmitSearchView with this android:imeOptions="actionDone|flagNoExtractUi"
You cannot overwrite this behavior.
A workaround could be to clear the filter, when a user exits the searchview.
You could use the OnCloseListener for this.
However, this can cause problems as well, depending on the minimum API Level you are developing for.
Another option is to trigger the onQueryTextChange method manually through a TextWatcher:
public class MyActivity extends Activity implements SearchView.OnQueryTextListener, TextWatcher {
// Basic onCreate(Bundle) here
#Override
public boolean onCreateOptionsMenu (final Menu menu) {
getMenuInflater().inflate(R.menu.myMenu, menu);
final SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
final SearchManager manager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(this);
final int resource_edit_text = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
((EditText) searchView.findViewById(resource_edit_text)).addTextChangedListener(this);
return super.onCreateOptionsMenu(menu);
}
// Implementation of TextWatcher, used to have a proper onQueryTextChange (it doesn't update when the last character is removed)
#Override
public void beforeTextChanged (final CharSequence charSequence, final int start, final int count, final int after) {}
#Override
public void onTextChanged (final CharSequence charSequence, final int start, final int before, final int after) {}
#Override
public void afterTextChanged (final Editable editable) {
if (editable.length() == 0)
onQueryTextChange(editable.toString());
}
// Implementation of OnQueryTextChangeListener
#Override
public boolean onQueryTextChange (final String query) {
// do stuff
return false;
}
#Override
public boolean onQueryTextSubmit (final String query) {
// do stuff
return false;
}
}
This all goes with all the default xml files which have been given up here, that is not the point of this answer. This is a workaround that I choose to use, feel free to use others
In my case I just wanted to enable user to clear his query as it was used as keyword in API search, so the simplest idea was:
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
userQuery = "";
}
});
where userQuery is my variable used for searching etc.
Hope it helps someone :)
Here is samvel1024's answer converted it to Kotlin.
You may need to change IME_ACTION_GO to whatever you're using for your keyboard's 'go' button. Simply run this method during your page initialization.
/**
* Business: User should be allowed to perform an empty search.
* SearchView does not cause OnQueryTextChange to fire when the box is empty.
* To create a listener method for this scenario, we use reflection to gain access to the SearchView's inner TextView.
*/
private fun enableEmptySearch(searchView: SearchView) {
try {
val searchViewClass = searchView::class.java
val currentListenerField: Field = searchViewClass.getDeclaredField("mOnEditorActionListener")
currentListenerField.isAccessible = true
val previousListener: TextView.OnEditorActionListener = currentListenerField.get(searchView) as TextView.OnEditorActionListener
val newListener: TextView.OnEditorActionListener = TextView.OnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_GO && v.text.isEmpty()) {
querySubmit()
}
previousListener.onEditorAction(v, actionId, event)
}
val innerTextViewField: Field = searchViewClass.getDeclaredField("mSearchSrcTextView")
innerTextViewField.isAccessible = true
(innerTextViewField.get(searchView) as TextView).setOnEditorActionListener(newListener) // Allow user to tap the "GO" button when the SearchView is empty.
} catch (ignored: Exception) {
// If a major change occurs to android SDK, internal fields mSearchSrcTextView or mOnEditorActionListener might not exist.
// This exception will prevent this additional feature from functioning, but not crash the app or cause any other issues.
}
}
For Koltin users:
Simply use the following instead of searchView.setOnQueryTextListener
val searchPlate = searchView.findViewById<EditText>(R.id.search_src_text)
searchPlate.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
searchYourItems(searchView.query.toString()) // your code goes here
}
false
}
This is how I do my basic search using the ActionBar Search widget. This is obviously the easy way where the suggestions are provided in a listView in the layout. But I want the suggestions inside the search box itself. Though it was possible to do it in a normal search box, how do I do the same using Actionbar Search box.
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
menu.add(0, 1, 1,"Search").setIcon(R.drawable.ic_search_inverse).setActionView(R.layout.collapsible_edittext).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) {
switch (item.getItemId()) {
case 1:
search = (AutoCompleteTextView) item.getActionView();
search.addTextChangedListener(filterTextWatcher);
search.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
return true;
}
return false;
}
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) {
// your search logic here
doGeoSearch(String.valueOf(s));
}
};
public void doGeoSearch(String query){
Geocoder geocoder;
ArrayList<Address> addresses;
ArrayList<String> address = new ArrayList<String>() ;
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = (ArrayList<Address>) geocoder.getFromLocationName(query, 6);
Log.d("Address",String.valueOf(addresses));
for(int i = 0;i<addresses.size();i++)
{
String addr = new String();
addr.concat(addresses.get(i).getAddressLine(0));
addr.concat(addresses.get(i).getAddressLine(1));
addr = addresses.get(i).getAddressLine(0) + addresses.get(i).getLocality() + addresses.get(i).getAdminArea();
//addr.concat(addresses.get(i).getAddressLine(2));
Log.d("addr",addr);
address.add(addr);
}
SearchAddressAdapater addressList = new SearchAddressAdapater(getApplicationContext(),R.layout.search_list,addresses, LocationActivity.this);
//addressView.setAdapter(addressList);
//ListView addressListView = new ListView();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You can add a search widget to your ActionBar Sherlock, the search dialog has this functionality and it is very simple to implement as it is a simple expandable action item.
This tutorial will show you how to do everything you need with the search widget including search suggestions
Even though the SearchView was implemented and works, the search suggestions work on newer devices, but don't work on older devices like Gingerbread. Here's an issue:
https://github.com/JakeWharton/ActionBarSherlock/issues/659
I have EditText field with android:numeric="decimal" and android:inputType="phone" for entering decimal numbers. I use input type phone because it is more easy to user enter numbers.
For any device with soft keyboard I haven't any problem but when I begin use hard keyboard when will print wrong numbers (for example when I use HTC Desire Z).
How to solve this problem?
P.S. I developed the "Simple Loan Calculator" for Android - it's opensource and freeware
Solved!
AndroidManifest.xml
<activity android:name=".MainActivity" android:label="#string/app_name" android:configChanges="keyboardHidden|orientation|keyboard" >
MainActivity.java
public void onCreate(Bundle savedInstanceState) {
....
setPriceInputFilter(amountEdit, interestEdit, fixedPaymentEdit, periodYearEdit, periodMonthEdit, downPaymentEdit, disposableCommissionEdit, monthlyCommissionEdit);
....
}
private void setPriceInputFilter(EditText ... fields){
PriceInputFilter filter = new PriceInputFilter();
for (EditText field: fields){
field.setFilters(new InputFilter[]{filter});
}
}
public void onConfigurationChanged(Configuration newConfig) {
if(newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO){
setInputType(InputType.TYPE_NULL, amountEdit, interestEdit, fixedPaymentEdit, periodYearEdit,
periodMonthEdit, downPaymentEdit, disposableCommissionEdit, monthlyCommissionEdit);
Toast.makeText(this, "HARD-keyboard", Toast.LENGTH_SHORT).show();
}else{
setInputType(InputType.TYPE_CLASS_PHONE, amountEdit, interestEdit, fixedPaymentEdit, periodYearEdit,
periodMonthEdit, downPaymentEdit, disposableCommissionEdit, monthlyCommissionEdit);
Toast.makeText(this, "SOFT-keyboard", Toast.LENGTH_SHORT).show();
}
super.onConfigurationChanged(newConfig);
}
private void setInputType(int type , EditText ... fields){
for (EditText field: fields){
field.setInputType(type);
}
}
PriceInputFilter.java
public class PriceInputFilter implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String checkedText = dest.toString() + source.toString();
String pattern = getPattern();
if (!Pattern.matches(pattern, checkedText)) {
return "";
}
return null;
}
private String getPattern() {
return "[0-9]+([.]{1}||[.]{1}[0-9]{1,2})?";
}
}