0

I've a textwatcher in which I am trying to implement some operations whenever the space key is pressed. But I want to make sure that after performing the operation I remove the spaces in the custom MultiAutoCompleteTextView control.

So I used the code written in the afterTextChanged event in order to replace all the spaces. But this results in onTextChanged event being called again and again until I get a StackOverflow runtime error.

I don't know what's causing the problem. Kindly help me out here.

public class ChipsMultiAutoCompleteTextview extends MultiAutoCompleteTextView implements OnItemClickListener {
private TextWatcher textWather = new TextWatcher() {

    public void onTextChanged(CharSequence s, int start, int before, int count) {

        if(count >=1)
        {
            if(s.charAt(start) == ' ')
            {
                setChips(getText().toString()); // generate chips
                updateInstruction(getText().toString(), false);
            }
            else
            {
                updateInstruction(getText().toString(), true);
            }

        }


    }
    public void beforeTextChanged(CharSequence s, int start, int count,int after) {}
    public void afterTextChanged(final Editable s) {
        String i = getText().toString().replaceAll("\\s","");
        setText(i);
        setSelection(i.length());
    }
};

public void setChips(String s){


    if(s.contains(" ") && !s.trim().equals("")) // check space in string
    {
        this.chips = s.trim().split(" ");

        SpannableStringBuilder ssb = new SpannableStringBuilder(getText());
        // split string wich comma
        int x =0;
        // loop will generate ImageSpan for every country name separated by comma
        for(String c : chips){
            // inflate chips_edittext layout 
            LayoutInflater lf = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            TextView textView = (TextView) lf.inflate(R.layout.chips_edittext, null);
            textView.setText(c); // set text


            setFlags(textView, c); // set flag image
            // capture bitmapt of genreated textview
            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),x ,x + c.length() , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            x = x+ c.length() +1;
        }


        // set chips span 
        setText(ssb);


        // move cursor to last 
        setSelection(s.length());
    }
}


public void updateInstruction(String s,boolean subtract) {

    String chipArray[] = s.trim().split(" ");

    int len;
    if(subtract)
        len = chipArray.length-1;
    else
        len = chipArray.length;

    int left = MINIMUM_REQUIRED_TAGS-len;   // chips required

    if(left<=0)
    {
        this.instruction.setText("");
        proceed = true;
    }
    else
    {
        proceed = false;
        this.instruction.setText(String.valueOf("Add atleast "+left+" topics..."));
    }
}
}
Mj1992
  • 3,404
  • 13
  • 63
  • 102
  • Well, it seems that the cause of the problem is that you may be updating the actual EditText/TextView where the textwatcher is actually watching for changes, and, inevitably when you do change that information programatically via the textwatcher, it is firing the same event again and again, which may lead to that issue. It seems that there may be a different approach for your actual need. – Ernani Joppert Aug 11 '14 at 03:18
  • @ErnaniJoppert you're right, that's exactly what's going on. I tried to implement this by using `onKeyListener` on the control and overriding `onKeyDown`, but these events does not seem to work. – Mj1992 Aug 11 '14 at 13:33

1 Answers1

0

Try this solution:

textView.setOnKeyListener(new OnKeyListener() {                 
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {

        // identify key pressed by checking keyCode value with KeyEvent.KEYCODE    
        if (keyCode == KeyEvent.KEYCODE_SPACE) {  
             // this is for backspace
        }

        return false;
    }
});

If that is not the case, try referring to this post which may contain the solution for your autocomplete behavior:

Ignore spaces while searching listview android

Community
  • 1
  • 1
Ernani Joppert
  • 503
  • 5
  • 12
  • @EmaniJoppert I've already tried the solution, the event doesn't call on each key hit. – Mj1992 Aug 12 '14 at 11:10
  • Have you tried both solutions, both the code and the link below? – Ernani Joppert Aug 13 '14 at 03:55
  • Yes I did a workaround, whenever I replace the spaces programatically, I set a boolean and the next time the textchanged event is called i directly return from the function based on that boolean. That solved it. But still don't know why the keyevent is not calling in side the class. – Mj1992 Aug 13 '14 at 11:17
  • @EmaniJoppert used the solution in the link also and your code solution also. Thanks for the help. – Mj1992 Aug 13 '14 at 11:19
  • Did it work or are you still stuck with it? Let's make it happen man! :) – Ernani Joppert Aug 13 '14 at 21:39
  • @EmaniJoppert, the workaround in the previous comment worked flawlessly. The `keylistener` and `OnkeyDown` solutions are not working. In the end I decided to create a custom view to solve the problem instead of using `compound drawables`. – Mj1992 Aug 14 '14 at 15:13
  • Ah, ok! Sometimes that's the best way to go! Hope you can eventually solve it the way you wanted...cheers pal! – Ernani Joppert Aug 14 '14 at 18:42