1

私は、ユーザーが数値のリアルタイムベース変換を行うことを可能にするアプリケーションを構築しています。ユーザーは編集テキストに数字を入力し、プラスとマイナスのボタンを使用してベースを選択します。これまでに遭遇した問題は、リアルタイム変換を提供しています。リサイクラビュー内のすべてのeditTextは、ベースに応じて変換できるBigIntegerにテキストを設定します。RecyclerView内のTextWatcher.onTextChanged()内でnotifyDataSetHasChanged()がエラーをスローする

私の考えは、ユーザーが新しい番号を入力しているときに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()))); 
    } 
} 

だしかし、どうやら私は、コンパイラは私にこのエラースローとしてTextWatcher.onTextChanged内部notifySetDataHasChanged()を呼び出すことは許されないのです。

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

自明きれいですが、残念ながら、私は可能な回避策を考え出していない。

答えて

1
view.post(

    new Runnable() { 

     public void run() { notifyDatasetChanged(); }; 
    } 


); 

自明:

コールRecyclerViewレイアウトやスクロールを計算した後に、この方法(次のループで)

以上説明: 同期

  • つのスレッド=コードフロー
  • メインスレッド=ルーパー
  • ルーパー=メッセージキュー=実行可能=ループ

他の解決策??

コールリサイクルビュー方式からU出口後

関連する問題