2017-02-14 61 views
3

我有一個簡單的RecyclerView顯示項目。目前,從RecyclerView.Adapter,我可以使用以下方法成功刪除項目。從對話框中刪除RecyclerView項目不更新

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

我把它從ViewHolder .The動畫的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

嘗試調製。代碼是正確的從列表中刪除位置。 我認爲問題是你從哪裏調用removeItem方法的按鈕的onclick事件,這裏只是檢查你是否傳遞正確的項目位置? –

+0

什麼是filteredDataSet?它有什麼價值? –

+0

@ keyur9779:傳遞的位置是正確的。 @quick學習者: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

如果您從onClickViewHolder類刪除,然後使用getAdapterPosition()獲得點擊的位置

如果這個代碼不工作,你能告訴什麼是你ViewHolder

+0

對不起,'onItemClick'是一個最初由'onClick'調用的接口方法。適配器位置通過位置參數在'onBindViewHolder(holder,position)'中設置。在今天上午進行了一些研究之後,我懷疑我可能需要使用'getAdapterPostition()',就像你所建議的那樣,點擊事件。 – anthony

+0

@anthony是否幫助我的解決方案 –

+0

直到今晚才能再次訪問此項目,如果有問題,我會將其標記爲已接受。謝謝。 – anthony

相關問題