【问题标题】:TextWatcher OnTextChanged keeps firingTextWatcher OnTextChanged 不断触发
【发布时间】:2014-08-09 21:09:36
【问题描述】:

我有一个 textwatcher,每当按下 space key 时,我都会尝试在其中执行一些操作。但我想确保在执行操作后,我删除了自定义 MultiAutoCompleteTextView 控件中的空格。

所以我使用afterTextChanged 事件中编写的代码来替换所有空格。但这会导致onTextChanged 事件被一次又一次地调用,直到我收到StackOverflow 运行时错误。

我不知道是什么导致了问题。请在这里帮助我。

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

【问题讨论】:

  • 好吧,问题的原因似乎是您可能正在更新实际的 EditText/TextView,其中 textwatcher 正在实际观察更改,并且,当您通过textwatcher,它一次又一次地触发相同的事件,这可能会导致该问题。看来您的实际需要可能有不同的方法。
  • @ErnaniJoppert 你是对的,这正是正在发生的事情。我尝试通过在控件上使用onKeyListener 并覆盖onKeyDown 来实现这一点,但这些事件似乎不起作用。

标签: android replace custom-controls textwatcher


【解决方案1】:

试试这个解决方案:

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

如果不是这样,请尝试参考这篇文章,其中可能包含您的自动完成行为的解决方案:

Ignore spaces while searching listview android

【讨论】:

  • @EmaniJoppert 我已经尝试过解决方案,事件不会在每次按键时调用。
  • 您是否尝试过两种解决方案,包括下面的代码和链接?
  • 是的,我做了一个解决方法,每当我以编程方式替换空格时,我都会设置一个布尔值,下次调用 textchanged 事件时,我会根据该布尔值直接从函数返回。那解决了它。但仍然不知道为什么 keyevent 没有在课堂上调用。
  • @EmaniJoppert 也使用了链接中的解决方案以及您的代码解决方案。感谢您的帮助。
  • 它奏效了还是你还在坚持?让我们让它发生吧! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-15
  • 2011-10-29
  • 1970-01-01
  • 2015-07-24
相关资源
最近更新 更多