2017-02-14 10 views
3

アイテムを表示するための簡単なRecyclerViewがあります。現在、RecyclerView.Adapterから、以下の方法で正常にアイテムを削除できます。RecyclerViewアイテムをダイアログボックスから削除します。

private void removeItem(int pos) {  
    filteredDataSet.remove(pos); 
    notifyItemRemoved(pos); 
    notifyItemRangeChanged(pos, getItemCount()); 
} 

私はViewHolder【選択アニメーションの仕事でonClick()関数からそれを呼び出すが、ビューが更新され、すべてが動作します。かなり標準のRecyclerView。

しかし、ユーザーにDialogでアイテムの削除を確認させてもらいたいのですが、ここで(不要なコードを除外)ダイアログの基本的な設定です:だから

... 

AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext()); 
builder.setTitle("Delete this item?"); 
builder.setView(layout); 

final int itemPos = pos; 

builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int id) { 
     removeItem(itemPos); 
    } 
}); 

... 

、私はちょうどダイアログのonClickListenerへのメソッド呼び出しを移動しています。

私が抱えている問題は、RecyclerViewが削除されたアイテムをアニメーション化すると、まったく同じ位置に戻ってアニメーション化され、リストは同じままであるということです。それはまだそこにあるように。私は下にスクロールする場合

しかし、私は、境界エラーの出る:それは実際には存在しないこと、およびとき、それがなくなって再びビューに戻ってくる

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position

を。つまり、キャッシュされていて、アダプタやデータセットを更新していないようです。私はそれがメインスレッドで呼び出される必要があることを読んで、私はこれに私のメソッドを変更しました:

private void removeItem(int pos) { 
final int itemPos = pos; 

Handler handler = new Handler(Looper.getMainLooper()); 
Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     filteredDataSet.remove(itemPos); 
     notifyItemRemoved(itemPos); 
     notifyItemRangeChanged(itemPos, getItemCount()); 
    } 
}; 
handler.post(runnable); 
} 

それはまだ動作していない、私は迷っています。私はそれがスレッドの問題だと思うが、どこからここに向かうべきか分からない。このコードは動作しない場合

+0

try to dubug。リストから位置を削除するコードは正しいです。 問題は、removeItemメソッドを呼び出す場所からのyesボタンのonclickイベントだと思います。ここで正しい項目の位置を渡しているかどうかを確認するだけです。 –

+0

filteredDataSetとは何ですか?それにはどんな値がありますか? –

+0

@ keyur9779:渡された位置が正しい。 @quick learner:filteredDataSetは、SQLデータベースを介して読み込まれる 'List <>'です。それは望むように機能している(もちろん、言及された問題を除いて)。 – anthony

答えて

1

からonItemClick()が何であるかを伝えることができますアイテムがデータベースから削除されたときにremoveItem()関数をトリガーします。どうやら、アイテムが実際にデータベースから削除される前に、アダプターに通知されていたようです。

私はDBFlowを使用してクエリを実行しているため、このソリューションはDBFlowベースのソリューションにのみ適用されます。これは、RecyclerViewを保持するビューから呼び出されます。

public void deleteItem(int pos, long id) { 
    DatabaseDefinition database = FlowManager.getDatabase(AppDatabase.class); 

    //hold id to remove later 
    final long tempId = id; 
    final int tempPos = pos; 

    final ItemModel currentItem = getItem(id); 

    Transaction transaction = database.beginTransactionAsync(new ITransaction() { 
     @Override 
     public void execute(DatabaseWrapper databaseWrapper) { 
      currentItem.delete(); 
     } 
    }).success(new Transaction.Success() { 
     @Override 
     public void onSuccess(Transaction transaction) { 
      mAdapter.removeItem(tempPos); //called here 
     } 
    }).error(new Transaction.Error() { 
     @Override 
     public void onError(Transaction transaction, Throwable error) { 
      Log.d("delete error", "item not deleted"); 
     } 
    }).build(); 

    transaction.execute(); 
} 
0

あなたがViewHolderクラスからonClickから削除する場合は、場所

をクリック取得するgetAdapterPosition()を使用しますが、この問題はにコールバックを使用することによって解決されたあなたのViewHolder

+0

申し訳ありません、onItemClickは、元々onClickによって呼び出されたインターフェイスメソッドです。アダプタの位置は、position引数で 'onBindViewHolder(holder、position)'に設定されています。今朝の少しの調査の後、クリックイベントのために、あなたが示唆したように、 'getAdapterPostition()'を使う必要があると思われます。 – anthony

+0

@anthony私の解決策は助けられます –

+0

今夜までこのプロジェクトに再び参加することはできません。ありがとう。 – anthony

関連する問題