当notifyDataSetHasChanged()在RecyclerView中的TextWatcher.onTextC



我正在构建一个应用程序,允许用户有一个数字的实时基数转换。用户在编辑文本中输入他们的数字,并使用加减号按钮选择基数。到目前为止,我遇到的问题是提供实时转换。回收器视图中的所有editText都将它们的文本设置为一个BigInteger,该BigInteger可以根据它们的基数进行转换。

我的想法是在用户输入新数字时更新BigInteger。因此,每当用户输入一个数字时,我应该能够更新BigInteger,通知回收器视图数据已更改,然后编辑文本视图应该自动更新。这是我的ConvertViewHolder

    public ConvertViewHolder(final View itemView) {
        super(itemView);
        mBaseTextView = (TextView) itemView.findViewById(R.id.baseLabel);
        mEditText = (EditText) itemView.findViewById(R.id.numberEditText);
        mMinusButton = (Button) itemView.findViewById(R.id.minusButton);
        mPlusButton = (Button) itemView.findViewById(R.id.plusButton);
        mRemoveButton = (ImageButton)itemView.findViewById(R.id.removeButton);
        mMinusButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mRoot.get(getPosition()) > MIN_BASE) {
                    mRoot.set(getPosition(), (mRoot.get(getPosition()) - 1));
                    notifyDataSetChanged();
                }
            }
        });
        mPlusButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mRoot.get(getPosition()) < MAX_BASE){
                    mRoot.set(getPosition(), (mRoot.get( getPosition() ) +1));
                    notifyDataSetChanged();
                }
            }
        });
        mRemoveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mRoot.remove(getPosition());
                notifyDataSetChanged();
            }
        });
        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void afterTextChanged(Editable editable) {
                if(editable.toString().length() > 0) {
                    // change Big Integer
                    mNumber.setDecimalNumber(editable.toString(), mRoot.get( getPosition() ) );
                    // notify change
                    notifyDataSetChanged();
                }
            }
        });

        // TODO: convert numbers at the same time
    }
    public void bindConverter(final int root){
        mBaseTextView.setText(String.format("%02d", root));
        // String containing all the allowed digits depending on base
        String digits = mNumber.getScaleFromBase(root);
        if (root < 11) {
            // filter input
            mEditText.setInputType(InputType.TYPE_CLASS_NUMBER |
                    InputType.TYPE_TEXT_FLAG_MULTI_LINE);
            mEditText.setKeyListener(DigitsKeyListener.getInstance(digits));
            mEditText.setSingleLine(false);
            mEditText.setMaxLines(2);
        } else {
            mEditText.setInputType(InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS |
                    InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
            mEditText.setSingleLine(false);
            mEditText.setMaxLines(2);
            mEditText.setImeOptions(EditorInfo.IME_FLAG_NO_ENTER_ACTION);
            // TODO: filter input for base higher than 10
        }
        // set editText to BigInteger displaying it in the correct base
        // i.e. if the BigInteger is "8" it will be displayed as 8 if the base is 10
        // and as 1000 if the base is 2
        mEditText.setText(mNumber.getDecimalNumber(mRoot.get( getPosition() )));
    }
}

但显然我不允许调用notifySetDataHasChanged内的TextWatcher.onTextChanged()作为编译器抛出我这个错误:

 java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling

这是不言自明的,但不幸的是,我还没有找到一个可能的解决方案。

view.post(
   new Runnable() {
        public void run() { notifyDatasetChanged(); };
   }

);

自我解释:

在RecyclerView计算布局或滚动(在下一个循环中)后调用此方法

更多的解释:

  • 一个线程=代码流同步
  • 主线程= loop
  • looper = message queue = runnable = loop

其他可能的解决方案??

从回收器视图中退出后调用

ps。

如果这段代码"将在更高的堆栈存在位置(在RecyclerView的GC作用域内)拉可运行程序,以减少资源使用和计算时间:)

private Runnable r = new Runnable {
     public void run() { notifyDatasetChanged(); }
}  
 ...
view.post(r);
 ...

或使用接口

的通用解决方案拉入方法
public Runnable postNotify(ListAdapter la) {
     return = new Runnable {
         public void run() { la.notifyDatasetChanged(); }
     };
 }  
 ...
 private Runnable changed = postNotify(adapter); 
 ...
 view.pos(changed);

相关内容

  • 没有找到相关文章

最新更新