How to add Icon in hint of EditText - android

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;
}

Related

multiline edittext where parts are not editable, like fill in the blanks

I need to have a view which contains textview and edittext.
Example:
Yay! you made it to ______ We should hang out! feel ____ to follow me.
Above "_____" could be of any length and it should feel like a paragraph in the end. Rest of the text given above is not changeable. Just like fill in the blanks.
From my perspective, a fill-in-the-blank widget should do the following:
Allow only certain identified portions of the text to be changed. The rest of the text is locked.
Not allow cursor movement into the locked text.
Flow from line to line like EditText.
Be generalized with variable placement of blanks.
Here is an implementation of such a widget based upon EditText. Editable spans are set up using a span (BlanksSpan) extended from StyleSpan. A blank span is identified by five underscores ("_____") in the text. Cursor movement is controlled in OnSelectionChanged() and various EditText callbacks. Changes to the text is monitor by a TextWatcher and adjustments to the displayed text are made there.
Here is the video of the widget in use:
FillInBlanksEditText.java
public class FillInBlanksEditText extends android.support.v7.widget.AppCompatEditText
implements View.OnFocusChangeListener, TextWatcher {
private int mLastSelStart;
private int mLastSelEnd;
private BlanksSpan mSpans[];
private Editable mUndoChange;
private BlanksSpan mWatcherSpan;
public FillInBlanksEditText(Context context) {
super(context);
init();
}
public FillInBlanksEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FillInBlanksEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSpans = setSpans();
setOnFocusChangeListener(this);
}
#Override
public void onRestoreInstanceState(Parcelable state) {
mSpans = null;
super.onRestoreInstanceState(state);
Editable e = getEditableText();
mSpans = e.getSpans(0, e.length(), BlanksSpan.class);
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
addTextChangedListener(this);
if (findInSpan(getSelectionStart(), getSelectionEnd()) != null) {
mLastSelStart = getSelectionStart();
mLastSelEnd = getSelectionEnd();
} else if (findInSpan(mLastSelStart, mLastSelEnd) == null) {
setSelection(getEditableText().getSpanStart(mSpans[0]));
}
} else {
removeTextChangedListener(this);
}
}
#Override
protected void onSelectionChanged(int selStart, int selEnd) {
if (!isFocused() || mSpans == null ||
(getSelectionStart() == mLastSelStart && getSelectionEnd() == mLastSelEnd)) {
return;
}
// The selection must be completely within a Blankspan.
final BlanksSpan span = findInSpan(selStart, selEnd);
if (span == null) {
// Current selection is not within a Blankspan. Restore selection to prior location.
moveCursor(mLastSelStart);
} else if (selStart > getEditableText().getSpanStart(span) + span.getDataLength()) {
// Acceptable location for selection (within a Blankspan).
// Make sure that the cursor is at the end of the entered data. mLastSelStart = getEditableText().getSpanStart(span) + span.getDataLength();
mLastSelEnd = mLastSelStart;
moveCursor(mLastSelStart);
} else {
// Just capture the placement.
mLastSelStart = selStart;
mLastSelEnd = selEnd;
}
super.onSelectionChanged(mLastSelStart, mLastSelEnd);
}
// Safely move the cursor without directly invoking setSelection from onSelectionChange.
private void moveCursor(final int selStart) {
post(new Runnable() {
#Override
public void run() {
setSelection(selStart);
}
});
// Stop cursor form jumping on move.
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
#Nullable
private BlanksSpan findInSpan(int selStart, int selEnd) {
for (BlanksSpan span : mSpans) {
if (selStart >= getEditableText().getSpanStart(span) &&
selEnd <= getEditableText().getSpanEnd(span)) {
return span;
}
}
return null;
}
// Set up a Blankspan to cover each occurrence of BLANKS_TOKEN.
private BlanksSpan[] setSpans() {
Editable e = getEditableText();
String s = e.toString();
int offset = 0;
int blanksOffset;
while ((blanksOffset = s.substring(offset).indexOf(BLANKS_TOKEN)) != -1) {
offset += blanksOffset;
e.setSpan(new BlanksSpan(Typeface.BOLD), offset, offset + BLANKS_TOKEN.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
offset += BLANKS_TOKEN.length();
}
return e.getSpans(0, e.length(), BlanksSpan.class);
}
// Check change to make sure that it is acceptable to us.
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
mWatcherSpan = findInSpan(start, start + count);
if (mWatcherSpan == null) {
// Change outside of a Blankspan. Just put things back the way they were.
// Do this in afterTextChaanged. mUndoChange = Editable.Factory.getInstance().newEditable(s);
} else {
// Change is OK. Track data length.
mWatcherSpan.adjustDataLength(count, after);
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Do nothing...
}
#Override
public void afterTextChanged(Editable s) {
if (mUndoChange == null) {
// The change is legal. Modify the contents of the span to the format we want.
CharSequence newContents = mWatcherSpan.getFormattedContent(s);
if (newContents != null) {
removeTextChangedListener(this);
int selection = getSelectionStart();
s.replace(s.getSpanStart(mWatcherSpan), s.getSpanEnd(mWatcherSpan), newContents);
setSelection(selection);
addTextChangedListener(this);
}
} else {
// Illegal change - put things back the way they were.
removeTextChangedListener(this);
setText(mUndoChange);
mUndoChange = null;
addTextChangedListener(this);
}
}
#SuppressWarnings("WeakerAccess")
public static class BlanksSpan extends StyleSpan {
private int mDataLength;
public BlanksSpan(int style) {
super(style);
}
#SuppressWarnings("unused")
public BlanksSpan(#NonNull Parcel src) {
super(src);
}
public void adjustDataLength(int count, int after) {
mDataLength += after - count;
}
#Nullable
public CharSequence getFormattedContent(Editable e) {
if (mDataLength == 0) {
return BLANKS_TOKEN;
}
int spanStart = e.getSpanStart(this);
return (e.getSpanEnd(this) - spanStart > mDataLength)
? e.subSequence(spanStart, spanStart + mDataLength)
: null;
}
public int getDataLength() {
return mDataLength;
}
}
#SuppressWarnings({"FieldCanBeLocal", "unused"})
private static final String TAG = "FillInBlanksEditText";
private static final String BLANKS_TOKEN = "_____";
}
activity_main.java
A sample layout.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.fillintheblanks.FillInBlanksEditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#android:color/transparent"
android:inputType="textMultiLine"
android:padding="16dp"
android:text="Yay! You made it to _____. We should hang out! Feel _____ to follow me."
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.example.fillintheblanks.FillInBlanksEditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#android:color/transparent"
android:inputType="textMultiLine"
android:padding="16dp"
android:text="_____ says that it is time to _____. Are you _____?"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/editText" />
</android.support.constraint.ConstraintLayout>
A few things to note:
In extracted mode, cursor placement jumps around if a touch is made outside of a BlanksSpan. Things still work but misbehave a little.
The length of the blanks fields is fixed, but it can be made variable in length with some additional work.
The action mode in the control needs some work based upon requirements.
multiline edittext where parts are not editable, like fill in the blanks
You can use a TextWatcher() for this requirement
Try this he is the little work around for this
MainActivity
public class MainActivity extends AppCompatActivity {
EditText myEditText;
String startText = "I'm The First Part";
String lastText = "I'm The Last Part";
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SpannableStringBuilder firstStringBuilder = new SpannableStringBuilder(startText);
final SpannableStringBuilder lastStringBuilder = new SpannableStringBuilder(lastText);
StyleSpan firstStyleSpan = new StyleSpan(android.graphics.Typeface.BOLD);
firstStringBuilder.setSpan(firstStyleSpan, 0, firstStringBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
lastStringBuilder.setSpan(firstStyleSpan, 0, lastStringBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
myEditText = findViewById(R.id.myEditText);
spannableStringBuilder.append(firstStringBuilder);
spannableStringBuilder.append(" ");
spannableStringBuilder.append(lastStringBuilder);
myEditText.setText(spannableStringBuilder);
Selection.setSelection(myEditText.getText(), startText.length() + 1);
myEditText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().startsWith(firstStringBuilder.toString())
|| !s.toString().contains(lastText)) {
Log.e("StringBuilder_TAG", spannableStringBuilder.toString());
myEditText.setText(spannableStringBuilder);
Selection.setSelection(myEditText.getText(), myEditText.getText().length() - lastStringBuilder.length() - 1);
} else {
spannableStringBuilder.clear();
spannableStringBuilder.append(s.toString());
Log.e("My_TAG", spannableStringBuilder.toString());
}
}
});
}
}
layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<EditText
android:id="#+id/myEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:padding="5dp" />
</LinearLayout>
Here is the output video of above code https://www.youtube.com/watch?v=pfhUzLiFD6U
using above code you able to make not editble first and last parts of editext
Note
You can also use a TextDrawable
here are some links for that
How to put text in a drawable?
https://github.com/amulyakhare/TextDrawable
Set unchangeable some part of editText android
You can also create a custom EditText for this
Adding a prefix to an EditText
You can also use InputFilter
Solution one
Try using flexbox-layout - https://github.com/google/flexbox-layout.
Solution Two
Use textWatcher
Solution Three
Use html, css and javascript to design a simple webpage.
Use webview to load the html file.
Follow #Cheticamp 's answer, it works when you set a SpannableString in a setText() method.
Also you should override setText() method and set Spans to mSpans:
#Override
public void setText(CharSequence text, BufferType type) {
mSpans = Editable.Factory.getInstance().newEditable(text).getSpans(0, text.length(), BlanksSpan.class);
Log.d(TAG, "setText: " + mSpans.length);
super.setText(text, type);
}
if you don't set a SpannableString, Editable interface will get a simple String without Spans.
So if you call methods like:
Editable.getSpanStart(tag) returns -1;
Editable.getSpanEnd(tag) returns -1;
Editable.getSpans(start, end, Class) returns empty array

android, block special character in searchview

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
}

Highlighting textview with color like Adobe PDF

I'm trying to add menu to focus textview to highlight a word or phrase.
Currently my code has issues
1. highlights more than one word if the word appears more than once
2. Highlighted color disappears on app exit.
TextView textView = (TextView) findViewById(R.id.textView);
textView.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
getMenuInflater().inflate(R.menu.h_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.highlight:
setTextBG();
return true;
default:
break;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
private void setTextBG() {
String selectedText = "";
if (textView.isFocused()) {
final int textStartIndex = textView.getSelectionStart();
final int textEndIndex = textView.getSelectionEnd();
int min = 0;
int max = textView.getText().length();
min = Math.max(0, Math.min(textStartIndex, textEndIndex));
max = Math.max(0, Math.max(textStartIndex, textEndIndex));
selectedText = textView.getText().subSequence(min, max).toString().trim();
}
int txt = textView.getText().toString().indexOf(selectedText, 0);
Spannable mywords = new SpannableString(textView.getText().toString());
for (int i = 0; i < textView.getText().toString().length() && whateva != -1;
i = whateva+1) {
txt = textView.getText().toString().indexOf(selectedText, i);
if (txt == -1) break;
else {
mywords.setSpan(new BackgroundColorSpan(Color.YELLOW), txt, txt+selectedText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(mywords, TextView.BufferType.SPANNABLE);
}
}
Toast.makeText(getApplicationContext(), selectedText, Toast.LENGTH_SHORT).show();
}
Please find below example for highlighting more than one word in content.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView textContent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textContent = (TextView) findViewById(R.id.txtContent);
highlightWords();
}
private void highlightWords() {
String content = "This is just a demo of how to highlight more than one word in Android";
textContent.setText(getSpannableWord(content));
}
private Spannable getSpannableWord(String content) {
Spannable spannableString = new SpannableString(content);
// Create list of highlighted word and add to list every time user highlights
ArrayList<HighlightedWord> words = new ArrayList<>();
//1st highlighted word
HighlightedWord highlightedWord1 = new HighlightedWord("demo", 15);
words.add(highlightedWord1);
//2nd highlighted word
HighlightedWord highlightedWord2 = new HighlightedWord("highlight", 30);
words.add(highlightedWord2);
for (HighlightedWord highlightedWord : words) {
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), highlightedWord.getStartIndex(),
highlightedWord.getStartIndex()+ highlightedWord.getWord().length(), Spannable
.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spannableString;
}
}
Thanks!

android change one word color on touch

I want to change the color of one word when I touch it.
For example: Hello, my name is Robert.
(by default, all black)
Now if the user touches the word "Robert", I want the color of "Robert" to change to RED.
How do I do that? (I'm new to Android)
textview.setTextColor() changes the whole thing, I only want one word.
I believe the SpannableString and ClickableSpan are the things you are looking for.
For more information, check this.
And Html.fromHtml is also work for this.
L. Swifter is on the right track.
Here's a very simple version you can build off of.
SpannableString spannableString = new SpannableString(yourstring);
ClickableSpan clickableSpan = new ClickableSpan() {
boolean clicked = false;
#Override
public void onClick(View view) {
clicked = true;
view.invalidate();
}
#Override
public void updateDrawState(TextPaint ds) {
if (this.clicked) ds.setColor(Color.RED);
}
};
spannableString.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(spannableString);
textview.setMovementMethod(LinkMovementMethod.getInstance());
start and end are the index positions of "Robert"
Make sure your setText is using the spannableString, not the original string.
Have fun!
You can add an HTML <font> tag to the TextView's text.
Use onTouch to calculate which word you just touched, look at this.
And :
TextView.setText(Html.fromHtml("assumble your html style string to change specified word color"));
Summarize the answer of L. Swifter and TML, also used the answer from
select a word on a tap in TextView/EditText
The following code should be work if you click any word in the TextView.
The color would be changed to red if you clicked it. Other words color will be reset to black.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView lTextView = (TextView) findViewById(R.id.textView);
breakEveryWord("Clickable words in text view ", lTextView);
}
...
private void breakEveryWord(String passage, final TextView pTextView) {
String definition = passage.trim();
pTextView.setMovementMethod(LinkMovementMethod.getInstance());
pTextView.setText(definition, TextView.BufferType.SPANNABLE);
final Spannable spans = (Spannable) pTextView.getText();
BreakIterator iterator = BreakIterator.getWordInstance(Locale.US);
iterator.setText(definition);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
.next()) {
String possibleWord = definition.substring(start, end);
if (Character.isLetterOrDigit(possibleWord.charAt(0))) {
ClickableSpan clickSpan = new CustomClickableSpan(possibleWord, new CallBack() {
#Override
public void clearAll() {
CustomClickableSpan[] toRemoveSpans = spans.getSpans(0, pTextView.getText().length(), CustomClickableSpan.class);
for (CustomClickableSpan toRemoveSpan : toRemoveSpans) {
toRemoveSpan.reset(pTextView);
}
}
});
spans.setSpan(clickSpan, start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
public static class CustomClickableSpan extends ClickableSpan {
final String mWord;
boolean clicked = false;
final CallBack mCallBack;
public CustomClickableSpan(String pWord, CallBack pCallBack) {
mWord = pWord;
mCallBack = pCallBack;
}
public void reset(View widget) {
clicked = false;
widget.invalidate();
}
#Override
public void onClick(View widget) {
Log.d("tapped on:", mWord);
mCallBack.clearAll();
clicked = true;
widget.invalidate();
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.BLACK);
if (this.clicked) ds.setColor(Color.RED);
}
}
public interface CallBack {
void clearAll();
}
}

Customize android search widget for scoped search

I want to implement search filter in my android application. I have gone through the examples on how to integrate search filter and able to understand how to integrate it in application. But my requirement is to provide scoped search based a filter while doing search. I have tried to search similar implementations but was not able to find any examples. Please check section Scoped Search in this UI Pattern collection, especially Dropbox example for iphone.
As mentioned before I was unable to find similar example in android but by looking at Dictionary.com 's application (snapshot shown below) I came to know that its possible in android also (of course by adding some more efforts in case its not possible with Search Widget itself). Can any one please provide any directions how I can implement similar scoped search in my application ?
Thanks for spending time on this.
I would do the following:
first i create a searchType layout for the alertdialog with the choose: (images, video, etc..)
then i create the activity for the search and implement the widget(like on android guide).
in the activity create a variable:
private String searchType = "";
then
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.YOUR_MENU, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat
.getActionView(menuItem);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
//HERE INSERT THE CODE ABOUT THE ALERT DIALOG FOR THE CHOOSE
//THEN INSERT THE aALERT DIALOG RESPONSE INTO THE searchType VARIABLE
}
}
I have created a custom search widget that does not make use of the built in search functionality. Its simple to implement and can provide information to the current activity.
It also uses an Autocomplete textview so you can use Autocomplete, you could alternatively just replace this with a normal EditText.
public class CustomViewSearch extends View {
private CustomAutoCompleteView searchEditText;
private boolean viewShown = false;
private ActionBar actionBar;
private InputMethodManager inputMethodManager;
private OnEditorActionSearchListener onEditorActionSearchListener;
private List<String> dataItems;
private ArrayAdapter<String> arrayAdapter;
public interface OnEditorActionSearchListener {
void onEditorActionSearch(String searchText);
void onTextChangedListener(String text);
List<String> getNewItemsForSuggestions(String text);
}
public void setOnEditorActionSearchListener(OnEditorActionSearchListener l) {
onEditorActionSearchListener = l;
}
// IMPORTANT: Provide your activity as the context
public CustomViewSearch(final Context context, List<String> items) {
super(context);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View searchView = inflater.inflate(R.layout.custom_view_search_widget, null);
actionBar = ((ActionBarActivity) context).getSupportActionBar();
inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setCustomView(searchView);
actionBar.setDisplayShowCustomEnabled(true);
dataItems = items;
searchEditText = (CustomAutoCompleteView) searchView.findViewById(R.id.edit_text_search);
searchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
onEditorActionSearchListener.onEditorActionSearch(searchEditText.getText().toString());
return true;
}
return false;
}
});
searchEditText.requestFocus();
searchEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
onEditorActionSearchListener.onTextChangedListener(s.toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
dataItems = onEditorActionSearchListener.getNewItemsForSuggestions(s.toString());
// update the adapater
arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_dropdown_item_1line, dataItems);
arrayAdapter.notifyDataSetChanged();
searchEditText.setAdapter(arrayAdapter);
}
});
ImageButton closeImageButton = (ImageButton) searchView.findViewById(R.id.image_button_search_close);
closeImageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (searchEditText.getText().length() > 0) {
searchEditText.setText("");
} else {
hideKeyboard();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayShowCustomEnabled(false);
viewShown = false;
}
}
});
viewShown = true;
showKeyboard();
}
public String actionClick() {
if (!viewShown) {
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
searchEditText.requestFocus();
showKeyboard();
viewShown = true;
return null;
} else {
return getSearchText();
}
}
public void showKeyboard() {
inputMethodManager.showSoftInput(searchEditText, InputMethodManager.SHOW_IMPLICIT);
}
public void hideKeyboard() {
inputMethodManager.hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
}
public String getSearchText() {
return searchEditText.getText().toString();
} }
The corresponding xml layout for the search :
<?xml version="1.0" encoding="utf-8"?>
<za.co.android.CustomAutoCompleteView android:id="#+id/edit_text_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/empty_layout"
android:paddingBottom="8dp"
android:textColor="#android:color/white"
android:singleLine="true"
android:imeOptions="actionSearch"
android:textCursorDrawable="#null"
android:paddingRight="36dp"
android:layout_alignParentLeft="true"
android:inputType="text"
android:hint="#string/search"
android:textColorHint="#color/palette_primary_light_grey"/>
<ImageButton
android:id="#+id/image_button_search_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:drawable/ic_menu_close_clear_cancel"
android:layout_toLeftOf="#+id/empty_layout"
android:layout_centerVertical="true"
android:layout_marginRight="4dp"/>
<FrameLayout
android:id="#+id/empty_layout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentRight="true">
</FrameLayout>
The custom autocomplete widget code:
public class CustomAutoCompleteView extends AutoCompleteTextView {
public CustomAutoCompleteView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomAutoCompleteView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomAutoCompleteView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
// this is how to disable AutoCompleteTextView filter
#Override
protected void performFiltering(final CharSequence text, final int keyCode) {
String filterText = "";
super.performFiltering(filterText, keyCode);
}
/*
* after a selection we have to capture the new value and append to the existing text
*/
#Override
protected void replaceText(final CharSequence text) {
super.replaceText(text);
}}
Usage of the CustomViewSearch widget:
Add a search icon to the menu.xml for the Activity. Then in the onOptionsItemSelected method - when the menu item is clicked, call the below function:
public void triggerSearch() {
if (customViewSearch == null) {
customViewSearch = new CustomViewSearch(this, null);
customViewSearch.setOnEditorActionSearchListener(new CustomViewSearch.OnEditorActionSearchListener() {
#Override
public void onEditorActionSearch(String searchText) {
// DO SOME STUFF
((AppItemListFragment_) getSupportFragmentManager()
.findFragmentById(R.id.appitem_list)).searchTriggered(searchText);
}
#Override
public void onTextChangedListener(String text) {
((AppItemListFragment_) getSupportFragmentManager()
.findFragmentById(R.id.appitem_list)).searchTriggered(text);
}
#Override
public List<String> getNewItemsForSuggestions(String text) {
return getNewAutoCompleteStrings(text);
}
});
} else {
String searchText = customViewSearch.actionClick();
if (searchText != null) {
// DO SOME STUFF
((AppItemListFragment_) getSupportFragmentManager()
.findFragmentById(R.id.appitem_list)).searchTriggered(searchText);
}
}}
I hope this helps - for me it was much easier to implement a custom search than use the built in one and provides a scoped search for any screen you are on.

Categories

Resources