【问题标题】:How do I get MultiAutoCompleteTextView tokenizer similar to Facebook app?如何获得类似于 Facebook 应用程序的 MultiAutoCompleteTextView 标记器?
【发布时间】:2013-08-09 20:11:10
【问题描述】:

我正在创建一个具有“收件人”字段的应用程序,就像 Facebook 应用程序的“新消息”功能一样。

从下拉列表中选择一个项目后,我创建一个图像跨度并将其添加到MultiAutoCompleteTextView。我在这个视图中使用了SpaceTokenizer。问题是当我点击退格时,光标首先移动到空白处(即空格Tokenizer),然后当我再次点击退格时,整个单词被删除......我想删除整个我第一次点击退格键就像 facebook 应用程序一样......

这是我的SpaceTokenizer代码

     multiContentText.setTokenizer(new Tokenizer(){
     public int findTokenStart(CharSequence text, int      cursor) {
        int i = cursor;
        if(i>0){
            Log.d("textchar ",""+text.charAt(i - 1));
        }

        while (i > 0 && text.charAt(i - 1) != ' ') {
            i--;
        }
        while (i < cursor && text.charAt(i) == ' ' || text.charAt(i - 1) == '\n') {
            i++;
        }

        return i;
    }

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

        while (i < len) {
            if (text.charAt(i) == ' ' || text.charAt(i - 1) == '\n') {
                return i;
            } else {
                i++;
            }
        }

        return len;
    }

    public CharSequence terminateToken(CharSequence text) {
        int i = text.length();
        while (i > 0 && text.charAt(i - 1) == ' ' || text.charAt(i - 1) == '\n') {
            i--;
        }

        if (i > 0 && text.charAt(i - 1) == ' ' || text.charAt(i - 1) == '\n') {
            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+" ";
            }
        }
    }
});

我正在使用此代码在我的多 ContentText 中创建 TextView

SpannableStringBuilder ssb = new SpannableStringBuilder(multiContentText.getText());
String c="text from the list";
TextView textView = (TextView) inflater.inflate(R.layout.chips_edittext, null);
textView.setText(c); // set text
int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
textView.measure(spec, spec);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(textView.getWidth(), textView.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
canvas.translate(-textView.getScrollX(), -textView.getScrollY());
textView.draw(canvas);
textView.setDrawingCacheEnabled(true);
Bitmap cacheBmp = textView.getDrawingCache();
Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true); 
textView.destroyDrawingCache();  // destory drawable
// create bitmap drawable for imagespan
BitmapDrawable bmpDrawable = new BitmapDrawable(viewBmp);               
bmpDrawable.setBounds(0, 0,bmpDrawable.getIntrinsicWidth(),bmpDrawable.getIntrinsicHeight());
// create and set imagespan 
ssb.setSpan(new ImageSpan(bmpDrawable),0 ,c.length() , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// set chips span 
multiContentText.setText(ssb);      
multiContentText.setSelection(multiContentText.getText().length());

我不确定空间 Tokenizer 是否适合这种行为...任何帮助或指点将不胜感激...

这里是截图以便更好地理解......

我有一个文本,后跟一个空格,然后是一个光标...如果我按退格键,它首先会移动到空白处,只有当我再次按退格键时,整个文本才会被删除....

这是另一个截图..

这里的光标并不完全在两个 TextViews 之间,这与 facebook 应用程序不同,这再次导致插入文本时出现一些问题...

【问题讨论】:

  • 您是否尝试在获取长度之前修剪字符序列文本??
  • 是的..我尝试修剪长度..当我这样做时,光标会立即出现在 textview 之后,这会导致建议列表消失,因为之前没有空格..我已经添加了截图这个问题,请看一下以便更好地理解。
  • 您好,您解决了这个问题吗?如果您有,请您发布示例代码.. @VijayRaj
  • 如果你想使用 goole 的代码,看看这个:plus.google.com/+RichHyndman/posts/TSxaARVsRjF,这里的代码:android.googlesource.com/platform/frameworks/ex/+/…
  • @VijayRaj 您好,您的回答解决了您的问题吗?因为它对我不起作用..请给我一些建议

标签: android android-layout android-edittext multiautocompletetextview


【解决方案1】:

找到解决方案....

将此文本观察器添加到多自动完成文本视图

private TextWatcher textWather = new TextWatcher() {
    int noOfCharAdded=0;int noOfCharDeleted=0;
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        startIdx=start;
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,int after) {
        noOfCharAdded=after;
        noOfCharDeleted=count;
    }
    @Override
    public void afterTextChanged(Editable s) {
        Editable buffer = s;
        int start = multiContentText.getSelectionStart()<0?0:multiContentText.getSelectionStart();
        int end = multiContentText.getSelectionEnd()<0?0:multiContentText.getSelectionEnd();
                if(noOfCharAdded==0 && noOfCharDeleted==1){ //if space is deleted
                        if (start == end && delPrevText) {                          
                            ImageSpan link[] = buffer.getSpans(start, end,ImageSpan.class);
                            if (link.length > 0) {                                  
                                buffer.replace(buffer.getSpanStart(link[0]),buffer.getSpanEnd(link[0]),"");
                                buffer.removeSpan(link[0]);
                            }
                        }
                        delPrevText=true; 
                        multiContentText.setSelection(multiContentText.getText().length());
                }
                else if(noOfCharAdded==0 && noOfCharDeleted>1){//if the whole word is deleted
                        if(buffer.length()>0){                                           
                            if(start<buffer.length()){
                               delPrevText=false;                                  
                               if(buffer.charAt(start)==' '){                                       
                                  buffer.replace(start,start+1,"");
                               }
                            }
                        }                      
                }               

    }
};

【讨论】:

  • 我无法将光标放在每一行中编辑文本的最后一块...你能帮帮我吗...@Vijay Raj
  • 我已经编辑了我的答案...我在 afterTextChange 方法中添加了multiContentText.setSelection(multiContentText.getText().length());
  • 感谢您的回复,我已经添加了上述行,我的问题是我在编辑文本中插入了 4 个联系人,添加它们后,所有气泡都在编辑文本中的 2 行中出现。然后,如果我将光标放在第一行的最后一个芯片上,那么光标正好放在芯片之后,而不是在令牌之后。但它应该在令牌生成器之后。 @Vijay Raj
  • 我也有这个问题...但是当您尝试删除该芯片时,即使该芯片后面的标记器也将被删除,然后光标将再次移动到末尾...跨度>
  • 嗨 Vijay,我也可以一键删除逗号。当我们用逗号删除图像跨度时,如何删除文本。我正在输入之后。所以我想从存储的值中删除该字符串。所以我需要那个已删除的字符串。请回复@Vijay Raj
【解决方案2】:

尝试将TextWatcher 添加到MultiAutoCompleteTextView。 保存当前文本并检查最后一个空格是否被删除。 如果是这样,请删除最后一个令牌。

【讨论】:

  • 我已经有了 MultiAutoCompleteTextView 的 textwatcher...并尝试了各种方法但找不到解决方案...如果您可以分享代码,那将是一个很大的帮助..
  • 你也在为此苦苦挣扎???。我被不同分辨率的手机卡住了,edittext 中的光标不闪烁。如果你解决了这类问题,请告诉我@VijayRaj
  • 是的...我面临同样的问题,光标在edittext中根本不可见...我还看到Google+应用程序不允许光标在两个文本之间。 .不知道他们是怎么做到的...
【解决方案3】:
Editable buffer = s;
int start = multiContentText.getSelectionStart()<0?0:multiContentText.getSelectionStart();
int end = multiContentText.getSelectionEnd()<0?0:multiContentText.getSelectionEnd();
if(noOfCharAdded==0 && noOfCharDeleted==1){ //if space is deleted
    if (start == end && delPrevText) {                          
        ImageSpan link[] = buffer.getSpans(start, end,ImageSpan.class);
        if (link.length > 0) {
            for(int i=0;i<contentArray.size();i++){
                JSONObject jo=contentArray.get(i);
                try {
                    int keyValue=jo.getInt("startIndx");//No i18N                                                                               
                    if(keyValue==buffer.getSpanStart(link[0])){                                                 
                           jo.put("isRemoved", true);   
                           contentArray.set(i,jo);                                              
                    }
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
            buffer.replace(buffer.getSpanStart(link[0]),buffer.getSpanEnd(link[0]),"");
            buffer.removeSpan(link[0]);
        }
    }
    delPrevText=true;
            multiContentText.setSelection(multiContentText.getText().length());                 
}
else if(noOfCharAdded==0 && noOfCharDeleted>1){//if the whole word is deleted
    if(buffer.length()>0){                                           
        if(start<buffer.length()){
           delPrevText=false;
           for(int i=0;i<contentArray.size();i++){
                JSONObject jo=contentArray.get(i);
                try {
                    int keyValue=jo.getInt("startIndx");//No i18N                                                                               
                    if(keyValue==start){                                
                           jo.put("isRemoved", true);   
                           contentArray.set(i,jo);                                              
                    }
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
           if(buffer.charAt(start)==' '){                                       
              buffer.replace(start,start+1,"");
           }
        }
    }              
}

【讨论】:

  • 如何将 clicklistener 添加到 textview 中的不同项目以删除文本。
猜你喜欢
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 2016-06-08
  • 2015-08-04
相关资源
最近更新 更多