2016-10-16 25 views
0

我在我的應用程序中實現了本教程https://www.youtube.com/watch?v=F8eQ_3pmT6Y以刪除recylerview項目。 當我長時間按一個項目時,刪除圖標將出現在工具欄上,每個行的複選框都會選擇要刪除的項目。但問題是,當我檢查第一個複選框時,第十個複選框也是複選框,第二個複選框是第11個複選框等等。 有沒有人知道爲什麼會發生。這是我的適配器和活動代碼抱歉,如果它長期帶有上下文操作模式的RecyclerView刪除項目問題

public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.contentViewHolder> { 
    ArrayList<Heyvon> heyvons = new ArrayList<>(); 
    MainActivity mainActivity; 
    Context context; 

    public ContentAdapter(Context context, ArrayList<Heyvon> heyvons) { 
     this.context = context; 
     this.heyvons = heyvons; 
     mainActivity = (MainActivity) context; 
    } 

    @Override 
    public contentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view, parent, false); 
     contentViewHolder contentViewHolder = new contentViewHolder(view, mainActivity); 

     return contentViewHolder; 
    } 

    @Override 
    public void onBindViewHolder(contentViewHolder holder, int position) { 
     holder.imageView.setImageResource(heyvons.get(position).getPics()); 
     holder.name.setText(heyvons.get(position).getName()); 
     holder.ghaza.setText(heyvons.get(position).getGhaza()); 
     if (!mainActivity.isInActionMode) { 
      holder.checkBox.setVisibility(View.GONE); 
     } else { 
      holder.checkBox.setVisibility(View.VISIBLE); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return heyvons.size(); 
    } 

    public void updateAdapter(ArrayList<Heyvon> list) { 
     for (Heyvon heyvon : list) { 
      heyvons.remove(heyvon); 
     } 
     notifyDataSetChanged(); 
    } 

    public static class contentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
     ImageView imageView; 
     TextView name, ghaza; 
     CheckBox checkBox; 
     MainActivity mainActivity; 
     CardView cardView; 

     public contentViewHolder(View itemview, MainActivity mainActivity) { 
      super(itemview); 
      imageView = (ImageView) itemview.findViewById(R.id.imageView); 
      name = (TextView) itemview.findViewById(R.id.tv_names_card); 
      ghaza = (TextView) itemview.findViewById(R.id.tv_ghaza_card); 
      checkBox = (CheckBox) itemview.findViewById(R.id.checkBox); 
      this.mainActivity = mainActivity; 
      cardView = (CardView) itemview.findViewById(R.id.cardview); 
      cardView.setOnLongClickListener(mainActivity); 
      checkBox.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View view) { 
      mainActivity.prepareSelection(view, getAdapterPosition()); 
     } 
    } 
} 

代碼在活動

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu_activity_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    if (item.getItemId() == R.id.item_delete) { 
     isInActionMode = false; 
     ContentAdapter contentAdapter = (ContentAdapter) adapter; 
     contentAdapter.updateAdapter(selectedlist); 
     ClearActionMode(); 
    } else if (item.getItemId() == android.R.id.home) { 
     ClearActionMode(); 
     adapter.notifyDataSetChanged(); 
    } 
    return true; 
} 

public void ClearActionMode() { 
    isInActionMode = false; 
    toolbar.getMenu().clear(); 
    toolbar.inflateMenu(R.menu.menu_activity_main); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(false); 
    counter_text_veiw.setVisibility(View.GONE); 
    counter_text_veiw.setText("0 item is selected"); 
    counter = 0; 
    selectedlist.clear(); 
} 

@Override 
public boolean onLongClick(View view) { 
    toolbar.getMenu().clear(); 
    toolbar.inflateMenu(R.menu.menu_action_mod); 
    counter_text_veiw.setVisibility(View.VISIBLE); 
    isInActionMode = true; 
    adapter.notifyDataSetChanged(); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    return false; 
} 

public void prepareSelection(View view, int position) { 
    if (((CheckBox) view).isChecked()) { 
     selectedlist.add(heyvons.get(position)); 
     counter = counter + 1; 
     updateCounter(counter); 
    } else { 
     selectedlist.remove(heyvons.get(position)); 
     counter = counter - 1; 
     updateCounter(counter); 
    } 
} 

public void updateCounter(int counter) { 
    if (counter == 0) { 
     counter_text_veiw.setText("0 item is selected"); 
    } else { 
     counter_text_veiw.setText(counter + " item is selected"); 
    } 
} 

@Override 
public void onBackPressed() { 
    if (isInActionMode) { 
     ClearActionMode(); 
     adapter.notifyDataSetChanged(); 
    } else { 
     super.onBackPressed(); 
    } 
} 

回答

1

您所遇到的問題很可能是由於RecyclerView的循環:當您選擇列表中的項目CheckBox已更新,但如果您滾動並且所選視圖被回收,您將看到一個不同的(不需要的)檢查。在你的情況下,RecyclerView可能會成爲一個Pool,它是9個元素大:第一個視圖被回收以顯示第10個等等。

這意味着,選中複選框的視圖將根據onBindViewHolder()從列表中的另一項填充數據,並顯示在屏幕的另一側,而不是創建新數據。顯然CheckBox仍然錯誤地檢查。

在某些滾動之後,先前選擇的項目也可能未被選中。

AdapteronBindViewHolder()您需要重置CheckBox狀態取決於是否這個項目已經實際選擇(該方法被稱爲每次RecyclerView內部的視圖中創建時間或再生紙):

@Override 
public void onBindViewHolder(contentViewHolder holder, int position) { 
    holder.imageView.setImageResource(heyvons.get(position).getPics()); 
    holder.name.setText(heyvons.get(position).getName()); 
    holder.ghaza.setText(heyvons.get(position).getGhaza()); 
    if (!mainActivity.isInActionMode) { 
     holder.checkBox.setVisibility(View.GONE); 
     // Uncheck everything 
     holder.checkBox.setChecked(false); 
    } else { 
     holder.checkBox.setVisibility(View.VISIBLE); 
     // Has this item been selected? 
     holder.checkBox.setChecked(mainActivity.isSelected(position)); 
    } 
} 

MainActivity你可以保持不只是選擇的對象使用ListSet或陣列他們在Adapter位置,而且還能跟蹤:

private List<Integer> selectedItemsPositions; 

prepareSelection應保持所選項目的位置:

public void prepareSelection(View view, int position) { 
    if (((CheckBox) view).isChecked()) { 
     selectedlist.add(heyvons.get(position)); 
     selectedItemsPositions.add(position); // Keep track of the position 
     counter = counter + 1; 
     updateCounter(counter); 
    } else { 
     selectedlist.remove(heyvons.get(position)); 
     selectedItemsPositions.remove(position); 
     counter = counter - 1; 
     updateCounter(counter); 
    } 
} 

和​​會這樣定義:

public boolean isSelected(int itemPosition) { 
    return selectedItemsPositions.contains(itemPosition); 
}