用编辑文本中的自定义建议词替换点击的词
Replace a tapped word with custom suggested words in edit text
我想在编辑文本中点击一个词。单击该词时,它应该在弹出窗口中显示一组自定义建议词 window,通过这些词可以用建议词替换前一个词。请帮我怎么做。 我输入单词时不应显示建议。
我已经实现了所需的功能。这不是一个非常优雅的解决方案。所以,如果你能让这段代码更高效,欢迎你。
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;
}
以下是 TouchableSpan class 的定义,它扩展了 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);
}
}
它将看起来像这样:
我想在编辑文本中点击一个词。单击该词时,它应该在弹出窗口中显示一组自定义建议词 window,通过这些词可以用建议词替换前一个词。请帮我怎么做。 我输入单词时不应显示建议。
我已经实现了所需的功能。这不是一个非常优雅的解决方案。所以,如果你能让这段代码更高效,欢迎你。
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;
}
以下是 TouchableSpan class 的定义,它扩展了 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);
}
}
它将看起来像这样: