I want to tap on a word in edit text. When the word is clicked, it should show a set of custom suggested words in a Popup window by which the former word can be replaced with the suggested word. Please help me how to do this. The suggestions should not be shown while I type the word.
Asked
Active
Viewed 627 times
0
-
Doesn't the EditText already do this since maybe at least Android 4.0? – OneCricketeer Apr 19 '16 at 23:34
-
Can you please give an example for that? – Partho Mandal Apr 19 '16 at 23:39
-
There is an image of it in this question. http://stackoverflow.com/q/9011944/2308683 – OneCricketeer Apr 19 '16 at 23:40
-
But I want to replace it with a custom set of words for that particular word only, and I don't want to include in android dictionary. I want the same feature, but using my own dictionary structure which will suggest only particular suggestions for those words. – Partho Mandal Apr 19 '16 at 23:49
-
You need to be more specific about the desired behavior. What makes a word "wrong"? Do you want your list to open for every word? How should you distinguish between a tap to reposition the cursor, and a tap to open the list? – Mike M. Apr 20 '16 at 01:25
-
Don't worry about the wrong part. Yes, I want my list to be open for every word. The list will be different for every word. What I am thinking is implement clickableSpan for each word. In the onClick method for each word, I am trying to set arrayAdapter in ListView for each of these words to show the suggested words. But I am getting errors. Please help me in this. – Partho Mandal Apr 20 '16 at 02:40
-
That's not how I'd do it, but if you want help fixing your current code, you need to post it, along with the errors you're getting. – Mike M. Apr 20 '16 at 02:55
-
Looks like `tokenList` is `null` in the `editText.setText()` call. – Mike M. Apr 20 '16 at 03:18
-
@MikeM. After fixing that error, I am getting the following error: 04-20 21:14:18.796 25967-25967/com.datumdroid.android.ocr.simple E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference Please give me suggestions regarding how to fix that error – Partho Mandal Apr 21 '16 at 04:21
-
`listview` is `null`. The `ListView` with ID `list` is apparently not in your current layout. – Mike M. Apr 21 '16 at 04:27
-
@MikeM. Thanks a lot !!! It worked. Now I will work on improving this feature. Do you know any way to include listview inside editText ? Such as the one shown in this link : http://stackoverflow.com/q/9011944/2308683 – Partho Mandal Apr 21 '16 at 04:43
-
Looks like a `PopupWindow` with a `ListView`. Getting it to align with a word in an `EditText` will take some work, though. – Mike M. Apr 21 '16 at 04:48
1 Answers
0
I have implemented the required feature. This is not a very elegant solution. So, if you can make this code more efficient, you are welcome.
String meow = "I dont like ASU at all"; // String supposed be set in edit text
final String[] tokens = meow.split("\\s+");
tokenList = new ArrayList<String>(Arrays.asList(tokens));
//Create a custom dictionary file which will be used in Suggested words
dictionary = new HashMap<String, List<String>>();
dictionary.put("I", Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
dictionary.put("dont", Arrays.asList("Mumbai", "Delhi", "Gwalior"));
dictionary.put("like", Arrays.asList("Phoenix", "Tucson", "Flagstaff"));
dictionary.put("ASU", Arrays.asList("UoFA", "UCSB", "UCLA"));
dictionary.put("at", Arrays.asList("Sameeran", "Nikhil", "Aniket"));
dictionary.put("all", Arrays.asList("asas", "dfdf", "tytyty"));
dictionary.put("Gwalior", Arrays.asList("hardwork", "maketh", "luck"));
if (meow != null || meow.length() != 0 ) {
_field.setMovementMethod(LinkMovementMethod.getInstance());
//set the text for edittext using addClickablePart() function
_field.setText(addClickablePart(meow, tokenList), EditText.BufferType.SPANNABLE);
}
// This function regenerates the clickable span after word replaced
public void tokenGenerator(){
String editText_sentence = _field.getText().toString();
_field.setMovementMethod(LinkMovementMethod.getInstance());
String[] intermediate_tokens = editText_sentence.split("\\s+");
ArrayList<String> intermediate_tokenList = new ArrayList<String>(Arrays.asList(intermediate_tokens));
_field.setText(addClickablePart(editText_sentence, intermediate_tokenList), EditText.BufferType.SPANNABLE);
//addClickable function defined here
public SpannableStringBuilder addClickablePart(String str, ArrayList<String> clickableWords) {
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
for (final String clickableWord : clickableWords) {
int idx1 = str.indexOf(clickableWord);
int idx2 = 0;
while (idx1 != -1) {
idx2 = idx1 + clickableWord.length();
final String clickString = str.substring(idx1, idx2);
// ssb.setSpan(new TouchableSpan(clickString), idx1, idx2, 0);
ssb.setSpan(new TouchableSpan(clickString) {
@Override
public void onClick(View view) {
final Spanned s = _field.getText();
final int start = s.getSpanStart(this);
final int end = s.getSpanEnd(this);
word = s.subSequence(start, end).toString();
final PopupWindow popupWindow = new PopupWindow(SimpleAndroidOCRActivity.this);
final ArrayList<String> bua = new ArrayList<String>(dictionary.get(clickableWord));
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_dropdown_item_1line,
bua);
final ListView listview = new ListView(SimpleAndroidOCRActivity.this);
final EditText addWord = new EditText(SimpleAndroidOCRActivity.this);
addWord.requestFocusFromTouch();
addWord.setInputType(InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE);
addWord.setImeOptions(EditorInfo.IME_ACTION_DONE);
addWord.setOnEditorActionListener(new TextView.OnEditorActionListener() {
//Press Done button to replace typed word
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
StringBuffer sb = new StringBuffer(s.toString());
sb.replace(start, end, addWord.getText().toString());
_field.setText(sb.toString());
tokenGenerator();
if (popupWindow != null) {
popupWindow.dismiss();
}
}
return false;
}
});
addWord.setHint("Add word");
listview.setAdapter(adapter);
listview.addFooterView(addWord,null, true);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
int itemPosition = position;
String itemValue = (String) listview.getItemAtPosition(position);
StringBuffer sb = new StringBuffer(s.toString());
sb.replace(start, end, itemValue);
_field.setText(sb.toString());
tokenGenerator();
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
if (popupWindow != null) {
popupWindow.dismiss();
}
}
});
// some other visual settings for popup window
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(true);
popupWindow.setWidth(400);
popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
popupWindow.setContentView(listview);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.rgb(229,197,175)));
int pos = _field.getSelectionStart();
Layout layout = _field.getLayout();
int line = layout.getLineForOffset(pos);
int baseline = layout.getLineBaseline(line);
int ascent = layout.getLineAscent(line);
int x = (int)layout.getPrimaryHorizontal(pos);
int y = baseline + ascent;
popupWindow.showAtLocation(view, Gravity.LEFT,x,y + 30);
popupWindow.showAsDropDown(view, 0, 0); // show popup like dropdown list
}
}, idx1, idx2, 0);
idx1 = str.indexOf(clickableWord, idx2);
}
}
return ssb;
}
The following is the definition for TouchableSpan class which extends clickableSpan class
public abstract class TouchableSpan extends ClickableSpan {
String clicked;
String word;
public TouchableSpan(String string) {
super();
clicked = string;
}
abstract public void onClick(View view);
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}
It will look something like this:

Partho Mandal
- 9
- 1
- 5