Java – recyclerview displays the deleted data on the list
I have implemented recyclerview with inbox style sliding view. When swiping my card, I deleted the list item using the following method:
public void removeItem(int position) {
countries.remove(position);
notifyItemRemoved(position);
}
Similarly, when I press fab, I use this method to add data,
public void addItem(String country) {
countries.add(country);
notifyItemInserted(countries.size());
}
However, when I delete a data item by sliding, it will be deleted from the ArrayList and recyclerview lists, but when I add data through fab, the deleted data will still be displayed in the list. I checked the ArrayList dataset. This is expected
In the screenshot above, you can see that string test is the newly added data. I have deleted the last two lines of data. It is displayed randomly
Complete code for my adapter and activity
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<String> countries;
private TextView tv_country;
public DataAdapter(ArrayList<String> countries) {
this.countries = countries;
}
@Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_layout, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
tv_country.setText(countries.get(i));
}
@Override
public int getItemCount() {
return countries.size();
}
public void addItem(String country) {
countries.add(country);
notifyItemInserted(countries.size());
}
public void removeItem(int position) {
countries.remove(position);
notifyItemRemoved(position);
}
public class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(View view) {
super(view);
tv_country = (TextView)view.findViewById(R.id.tv_country);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ArrayList<String> countries = new ArrayList<>();
private DataAdapter adapter;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews(){
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(this);
recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new linearlayoutmanager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
adapter = new DataAdapter(countries);
recyclerView.setAdapter(adapter);
countries.add("Australia");
countries.add("India");
countries.add("United States of America");
countries.add("Germany");
countries.add("Russia");
adapter.notifyDataSetChanged();
itemtouchhelper.SimpleCallback simpleItemTouchCallback = new itemtouchhelper.SimpleCallback(0, itemtouchhelper.LEFT | itemtouchhelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
if (direction == itemtouchhelper.LEFT){
adapter.removeItem(position);
}
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
Paint p = new Paint();
Bitmap icon;
if(actionState == itemtouchhelper.ACTION_STATE_SWIPE){
View itemView = viewHolder.itemView;
if(dX > 0){
p.setColor(Color.parseColor("#388E3C"));
c.drawRect((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom(), p);
icon = BitmapFactory.decodeResource(
getResources(), R.drawable.ic_edit_white);
float height = (float) itemView.getBottom() - (float) itemView.getTop();
float width = height / 3;
RectF dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ width+width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,dest,p);
} else {
p.setColor(Color.parseColor("#D32F2F"));
c.drawRect((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom(), p);
icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_delete_white);
float height = (float) itemView.getBottom() - (float) itemView.getTop();
float width = height / 3;
RectF dest = new RectF((float) itemView.getRight() - width - width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
c.drawBitmap(icon,null,dest,p);
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
itemtouchhelper itemtouchhelper = new itemtouchhelper(simpleItemTouchCallback);
itemtouchhelper.attachToRecyclerView(recyclerView);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.fab:
adapter.addItem("Test");
Log.d("Raj",countries.toString());
break;
}
}
}
What have I tried
I tried using notifyitemrangechanged() like this:
public void removeItem(int position) {
countries.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, countries.size());
}
resolvent:
I'm not sure this will solve your problem, but one thing is incorrect is how you bind data. TV_ Country should not be part of the DataAdapter; It should be part of every viewholder. One of the reasons we use viewholder mode is to keep a simple reference to the views in each row
Your bind method should be similar to:
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
viewHolder.tv_country.setText(countries.get(i));
}
And ensure that TV_ Country is set as the public field of the internal viewholder class
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView tv_country;
public ViewHolder(View view) {
super(view);
tv_country = (TextView) view.findViewById(R.id.tv_country);
}
}