用编辑文本中的自定义建议词替换点击的词

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

}

它将看起来像这样: