30

我的应用程序中有一个 AutoCompleteTextView。该应用程序使用 Facebook SDK。我在 SO: https ://stackoverflow.com/a/12363961/450534上遵循了这个问题的代码,并进行了有效的搜索(过滤)活动。

现在,我如何在输入@符号后获得像 Facebook 应用程序一样的内联自动完成功能,并且仍然保留用户输入的其他文本?有问题的活动用于状态更新,并且可以包含用户的朋友以及其他文本。theAutoCompleteTextView或 theEditText自然会是多行的。对于您看到的状态更新。

我知道由于这篇文章中缺少任何代码,我可能会面临被否决甚至可能关闭问题的风险。但它确实是一个标准的样板列表过滤代码。

编辑:Android 的FriendCaster应用程序也是如此。

4

2 回答 2

36

首先将您的 EditText 变成 MultiAutoCompleteTextView。MultiAutoCompleteTextView 允许您替换文本的某些部分,例如“@”之后的文本。

你可以这样做:

final MultiAutoCompleteTextView inputEditText = (MultiAutoCompleteTextView) dialog.findViewById(R.id.MyEditText);

String[] COUNTRIES = new String[] { "Belgium", "France", "Italy", "Germany", "Spain" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES);
inputEditText.setAdapter(adapter);
inputEditText.setThreshold(1); //Set number of characters before the dropdown should be shown

//Create a new Tokenizer which will get text after '@' and terminate on ' '
inputEditText.setTokenizer(new Tokenizer() {

  @Override
  public CharSequence terminateToken(CharSequence text) {
    int i = text.length();

    while (i > 0 && text.charAt(i - 1) == ' ') {
      i--;
    }

    if (i > 0 && text.charAt(i - 1) == ' ') {
      return text;
    } else {
      if (text instanceof Spanned) {
        SpannableString sp = new SpannableString(text + " ");
        TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0);
        return sp;
      } else {
        return text + " ";
      }
    }
  }

  @Override
  public int findTokenStart(CharSequence text, int cursor) {
    int i = cursor;

    while (i > 0 && text.charAt(i - 1) != '@') {
      i--;
    }

    //Check if token really started with @, else we don't have a valid token
    if (i < 1 || text.charAt(i - 1) != '@') {
      return cursor;
    }

    return i;
  }

  @Override
  public int findTokenEnd(CharSequence text, int cursor) {
    int i = cursor;
    int len = text.length();

    while (i < len) {
      if (text.charAt(i) == ' ') {
        return i;
      } else {
        i++;
      }
    }

    return len;
  }
});

一个“问题”是弹出窗口将出现在 EditText 视图下。要将其向上移动并将其放在当前编写的文本下,您可以执行以下操作:

inputEditText.addTextChangedListener(new TextWatcher() {

  @Override
  public void onTextChanged(CharSequence s, int start, int before, int count) {
    Layout layout = inputEditText.getLayout();
    int pos = inputEditText.getSelectionStart();
    int line = layout.getLineForOffset(pos);
    int baseline = layout.getLineBaseline(line);

    int bottom = inputEditText.getHeight();

    inputEditText.setDropDownVerticalOffset(baseline - bottom);

  }

  @Override
  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  }

  @Override
  public void afterTextChanged(Editable s) {
  }
});

注意:如果 edittext 中的行数超过 edittext 可以显示的行数,这目前不考虑下拉位置。

于 2012-10-09T08:27:54.953 回答
0

https://github.com/dhaval001/linkable_text_view.git

在带有多自动完成文本视图的 Android TextView 和 EditText 中创建链接文本的简单方法,例如 @username 或 #hashtag。链接facebook和instagram

特征

匹配单个字符串或正则表达式模式以设置链接 更改链接文本的颜色 设置链接文本的样式:BOLD、ITALIC 或 BOLD_ITALIC 设置链接文本的下划线 指定特定单词的单击操作 OnTextChangedListener 监听器 LinkableEditText

于 2016-03-01T12:59:26.793 回答