How do I get MultiAutoCompleteTextView tokenizer similar to Facebook app?
Asked Answered
G

3

10

I am creating an application which has a 'To' field just like in Facebook app's "New Message" feature.

After selecting an item from the drop down list, I create an imagespan and add it to the MultiAutoCompleteTextView. I have used SpaceTokenizer for this view . The problem is when I click on backspace, the cursor first moves to the empty space (i.e., space Tokenizer) and then when I click on the backspace again, the whole word gets deleted....I want to delete the whole word on my first click of backspace just like facebook app...

Here is my code for 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+" ";
            }
        }
    }
});

I am using this code to create a TextView in my multi-ContentText

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

I am not sure whether the space Tokenizer is the right option for this type of behavior...Any help or pointers will be grateful...

Here is the screenshot for better understanding....

enter image description here

I have a text followed by a space and then a cursor...If I hit backspace, it first moves to the empty space and only when I hit backspace again the whole text is deleted....

Here is the another screenshot ..

enter image description here

Here the cursor is not exactly in between the two TextViews unlike in facebook app which again causes some issues in inserting the text...

Gilmer answered 8/8, 2013 at 7:41 Comment(5)
did you try trimming the charsequence text prior to taking its length??Scintillation
Yes..I tried trimming the length..when i do that, the cursor comes immediately after the textview which causes the suggestion list to disappear as there is no space before..I have added screenshots in the question, plz look at that for better understanding.Gilmer
Hi Did you resolved this Issue. Can you please post Sample code for that if u have.. @GilmerTetrasyllable
if you wish to use goole's code for this, check out this: plus.google.com/+RichHyndman/posts/TSxaARVsRjF , code here: android.googlesource.com/platform/frameworks/ex/+/…Certifiable
@Gilmer hi have you solved your issue from your answer?because its not working for me..plz give me some sugggestionsLatticework
G
4

Found the solution....

Add this textwatcher to the multiautocompletetextview

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

    }
};
Gilmer answered 4/9, 2013 at 11:28 Comment(9)
i am unable to put the cursor at the last chip of the edit text in every line... can u please help me... @Vijay RajMartlet
i have edited my answer...i have added multiContentText.setSelection(multiContentText.getText().length()); in afterTextChange methodGilmer
Thanks for the reply i added the above line already, My Problem is i have inserted 4 contacts in the edit text, after adding them all bubbles came in 2 lines in edit text . then if i put cursor at the last chip of first row then cursor is placing in after the chip exactly but not after the token.but it shud be at after the tokenizer. @Vijay RajMartlet
i too have that problem...but when you try to delete that chip, even the tokenizer following that chip will also be deleted and then the cursor will again move to the end...Gilmer
Hi Vijay, I am also able to delete the comma for one click. How can i get deleted Text when we delete the image span with comma. i am stroing the after enetering .so i want to delete that string from stored values. so i need that deleted string.. Please reply @Vijay RajMartlet
When you click the item from the suggestions list, store the text along with the start position in a hash map....You will know the start position of the deleted text and then you can retrieve the text from the hash mapGilmer
Thanks. how can i know that start position of the text while deleting with out getting the exact stored text. Please reply @Vijay RajMartlet
I m using JSONObject to store the text and the start postion...Wen I delete any chip, i delete that object from my jsonarray....Try this code in afterTextChanged method which I have added below..Gilmer
Hi I used multi auto complete textview for select multiple contacts for to address, I have custom adapter with object list,once user choose contacts i want to get user selected contact list from multi auto complete textview. how can i get? (because user can remove already selected contact while press back space) . can you please post sample here.Discoverer
S
2

Try adding a TextWatcher to the MultiAutoCompleteTextView. Save the current text and check if the last space was deleted. If so, remove the last token.

Swenson answered 28/8, 2013 at 11:43 Comment(3)
I already have textwatcher to the MultiAutoCompleteTextView...and tried various methods but couldn't find the solution...If you can share the code it will be a great help..Gilmer
you are also struggling with this???.i got stuck with different resolution mobiles that cursor in edittext is not blinking. if u resolved this kind of issue please let me know @GilmerTetrasyllable
Yeah...I m facing with the same issue where the cursor is not at all visible in edittext...I also saw Google+ app where they don't allow the cursor between the two text..Have no idea how do they do that...Gilmer
G
2
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,"");
           }
        }
    }              
}
Gilmer answered 27/9, 2013 at 9:28 Comment(1)
how you add the clicklistener to the different item in the textview to delete the text.Cornellcornelle

© 2022 - 2024 — McMap. All rights reserved.