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...

Sufian
  • 6,405
  • 16
  • 66
  • 120
VijayRaj
  • 425
  • 1
  • 4
  • 22
  • did you try trimming the charsequence text prior to taking its length?? – Snehal Poyrekar Aug 28 '13 at 11:42
  • 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. – VijayRaj Aug 29 '13 at 06:18
  • Hi Did you resolved this Issue. Can you please post Sample code for that if u have.. @VijayRaj – Roster Aug 29 '13 at 12:12
  • if you wish to use goole's code for this, check out this: https://plus.google.com/+RichHyndman/posts/TSxaARVsRjF , code here: https://android.googlesource.com/platform/frameworks/ex/+/android-sdk-support_r11 – android developer Apr 03 '14 at 09:32
  • @VijayRaj hi have you solved your issue from your answer?because its not working for me..plz give me some sugggestions – dipali Nov 08 '16 at 05:34

3 Answers3

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

    }
};
VijayRaj
  • 425
  • 1
  • 4
  • 22
  • i am unable to put the cursor at the last chip of the edit text in every line... can u please help me... @Vijay Raj – AndroidDev Sep 25 '13 at 06:29
  • i have edited my answer...i have added `multiContentText.setSelection(multiContentText.getText().length());` in afterTextChange method – VijayRaj Sep 25 '13 at 09:43
  • 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 Raj – AndroidDev Sep 25 '13 at 09:54
  • 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... – VijayRaj Sep 25 '13 at 10:58
  • 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 Raj – AndroidDev Sep 27 '13 at 06:12
  • 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 map – VijayRaj Sep 27 '13 at 08:51
  • Thanks. how can i know that start position of the text while deleting with out getting the exact stored text. Please reply @Vijay Raj – AndroidDev Sep 27 '13 at 09:02
  • 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.. – VijayRaj Sep 27 '13 at 09:29
  • 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. – Manikandan Dec 07 '14 at 08:02
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.

flx
  • 14,146
  • 11
  • 55
  • 70
  • 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.. – VijayRaj Aug 29 '13 at 06:21
  • 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 @VijayRaj – Roster Aug 30 '13 at 05:42
  • 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... – VijayRaj Aug 30 '13 at 06:43
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,"");
           }
        }
    }              
}
Sufian
  • 6,405
  • 16
  • 66
  • 120
VijayRaj
  • 425
  • 1
  • 4
  • 22
  • how you add the clicklistener to the different item in the textview to delete the text. – Nambi Nov 30 '13 at 13:51