简体   繁体   中英

How to Delete Item Without Deleting Position in Recycler View?

I really need your help. I've searched Google many days with many keywords, but I couldn't get it. So, I decided to ask to you.

So, here it is. Actually, I have one button in RecyclerView, but this button is repeated as much amount of data available, there are: Button with text "Baca 3x", "Baca 4x", and so on. I want, if I click button with text "Baca 3x" 3 times, it will change to "Baca 2x" >> "Baca 1x" >> remove item. Also if I click button with text "Baca 4x" 4 times, it will change to "Baca 3x" >> "Baca 2x" >> "Baca 1x" >> remove item.

But my problem is, I can't treat every button with different treatment, because every time the item has been deleted, position of data changes automatically. Because of this, I can't get specific button. For example: There is two button,

 1. Button "Baca 3x" on position 0
 2. Button "Baca 4x" on position 1

If button "Baca 3x" on position 0 has been deleted, so button "Baca 4x" changed it's position automatically to 0. The problem lays here.

Until now I just get every button based on their positions, which is a problem for me. Because of this I am thinking about How to Delete Item Without Deleting Position in Recycler View? Can you guys solve my problem? Should I use DiffUtil?And how to use it? Below the complete code I use:

ModelDoa.java

public class ModelDoa {

public static final int DOA_PAGI = 0;
public static final int DOA_SORE = 1;
public static final int DOA_MASJID = 2;
public static final int DOA_BANGUNT = 3;
public static final int DOA_MAU_TIDUR = 4;

private String mName;
private String bName;
private int mType;

public ModelDoa(String name, String butong, int type) {
    this.mName = name;
    this.bName = butong;
    this.mType = type;
}

public String getName() {
    return mName;
}

public void setName(String name) {
    this.mName = name;
}


public int getType() {
    return mType;
}

public void setType(int type) { this.mType = type; }


public String ambilName() {
    return bName;
}

public void setNama(String butonk) {
    this.bName = butonk;
}

}

AdapterDoa.java

public class AdapterDoa extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

public List<ModelDoa> mList;

public AdapterDoa(List<ModelDoa> list) {

    this.mList = list;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    switch (viewType) {

        case DOA_PAGI:
            View vieu = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
            PagiViewHolder rcv = new PagiViewHolder(vieu, this);
            return rcv;

        case DOA_SORE:
            View doa = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
            SoreViewHolder mdoa = new SoreViewHolder(doa);
            return mdoa;

        case DOA_MASJID:
            View dMasjid = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
            MasjidViewHolder mMasjid = new MasjidViewHolder(dMasjid);
            return mMasjid;

        case DOA_BANGUNT:
            View dBangunt = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
            BanguntViewHolder mBangunt = new BanguntViewHolder(dBangunt);
            return mBangunt;

        case DOA_MAU_TIDUR:
            View regut = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
            MauTidurViewHolder turu = new MauTidurViewHolder(regut);
            return turu;
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    ModelDoa object = mList.get(position);

    if (object != null) {

        switch (object.getType()) {

            case DOA_PAGI:
                ((PagiViewHolder) holder).mTitle.setText(object.getName());
                ((PagiViewHolder) holder).tombolbaca.setText(object.ambilName());
                break;

            case DOA_SORE:
                ((SoreViewHolder) holder).mTitle.setText(object.getName());
                ((SoreViewHolder) holder).tombolbaca.setText(object.ambilName());
                break;

            case DOA_MASJID:
                ((MasjidViewHolder) holder).mTitle.setText(object.getName());
                ((MasjidViewHolder) holder).tombolbaca.setText(object.ambilName());
                break;

            case DOA_BANGUNT:
                ((BanguntViewHolder) holder).mTitle.setText(object.getName());
                ((BanguntViewHolder) holder).tombolbaca.setText(object.ambilName());
                break;

            case DOA_MAU_TIDUR:
                ((MauTidurViewHolder) holder).mTitle.setText(object.getName());
                ((MauTidurViewHolder) holder).tombolbaca.setText(object.ambilName());
                break;
        }
    }
}

public void deleteItem(int position) {
    mList.remove(position); // hapus list
    notifyItemRemoved(position); // hapus tampilan
    // notifyItemRangeChanged( position, mList.size());
}

@Override
public int getItemCount() {
    if (mList == null)
        return 0;
    return mList.size();
}

@Override
public int getItemViewType(int position) {
    if (mList != null) {
        ModelDoa object = mList.get(position);
        if (object != null) {
            return object.getType();
        }
    }
    return 0;
}


}

PagiViewHolder.java

public class PagiViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle;
public Button tombolbaca;
public Button teksbaca;
public Button tombolshare;
private RelativeLayout rl2;
private int klik10 = 10;
private AdapterDoa myAdapter;

public PagiViewHolder(View itemView, AdapterDoa myAdapter) {
    super(itemView);
    this.myAdapter = myAdapter;

    itemView.setOnClickListener(mainViewClickListener);
    mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
    tombolbaca = (Button) itemView.findViewById(R.id.buttonbaca);
    tombolshare = (Button) itemView.findViewById(R.id.buttonshare);
    tombolbaca.setOnClickListener(bacaClickListener);
    tombolshare.setOnClickListener(shareClickListener);
    rl2 = (RelativeLayout) itemView.findViewById(R.id.relmasjid);
}

private View.OnClickListener bacaClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {

        teksbaca = (Button) v.findViewById(R.id.buttonbaca);

        // Baca 10x
        if( getAdapterPosition() ==0 ) {
            klik10--;
            teksbaca.setText("Baca " + klik10 + "x");

            if (klik10 <= 0)
            {
                // modify listItems however you want... add, delete, shuffle, etc
                myAdapter.deleteItem(getAdapterPosition());
            }
        }

    } // onclick
};

private View.OnClickListener shareClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        // Do button click handling here
            Intent sendIntent = new Intent();
            sendIntent.setAction(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_TEXT, mTitle.getText().toString() + "\n \n download aplikasinya di: http://www.tauhid.or.id" );
            sendIntent.setType("text/plain");
            Intent.createChooser(sendIntent,"Share via");
            v.getContext().startActivity(sendIntent);
    }
};

private View.OnClickListener mainViewClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        // Do button click handling here
    }
};


}

DoaPagi.java

public class DoaPagi extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_doa_pagi);

    // toolbar
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    //this line shows back button
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    List<ModelDoa> rowListItem =  getData();
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(DoaPagi.this);
    RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    mRecyclerView.setLayoutManager(linearLayoutManager);
    mRecyclerView.setHasFixedSize(true);
    AdapterDoa rcAdapter = new AdapterDoa(rowListItem);
    mRecyclerView.setAdapter(rcAdapter);

}

private List<ModelDoa> getData() {

    String[] data = getResources().getStringArray(R.array.doapagi);
    String[] baca = getResources().getStringArray(R.array.bacapagi);

    List<ModelDoa> list = new ArrayList<ModelDoa>();

    for (int i = 0; i < data.length; i++) {
            list.add(new ModelDoa(data[i], baca[i], ModelDoa.DOA_PAGI));
    }

    return list;
}

// Agar back button pada halaman induk settings berfungsi
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            this.finish();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

}

UPDATE (FIX CODE) By: Krishna Sharma : https://github.com/seadclark/RecyclerViewWithButtonClicks

Instead of removing the item from your list AND updating the interface, have two methods. One of them (deleteItem) will only delete the item and the other (deleteItemAndUpdate) will delete the item and update the interface.

public void deleteItem(int position) {
    mList.remove(position); // hapus list
}

public void deleteItemAndUpdate(int position) {
    mList.remove(position); // hapus list
    notifyItemRemoved(position); // hapus tampilan
}

In the future, you can decide whether you want to only remove the item from your list OR remove the item and update the UI.

EDIT 1:

You need to keep track of the amount of times that each item was clicked. We can call this value readCount. Every time that the item is clicked, we subtract 1 from this value. When this value reaches 0, we remove it from the list.

ModelDoa:

public class ModelDoa {

    private int readCount = 10;

    public int getReadCount() {
        return this.readCount;
    }

    public void setReadCount(int readCount) {
        this.readCount = readCount;
    }
}

PagiViewHolder:

private View.OnClickListener bacaClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        teksbaca = (Button) v.findViewById(R.id.buttonbaca);
        ModelDoa modelDoa = mAdapter.getItem(getAdapterPosition());

        if (modelDoa != null) {
            modelDoa.setReadCount(modelDoa.getReadCount() - 1);
            if (modelDoa.getReadCount() <= 0) {
                myAdapter.deleteItem(getAdapterPosition());
            }
            teksbaca.setText("Baca " + modelDoa.getReadCount() + "x");
        }
    }
};

AdapterDoa:

public ModelDoa getItem(int position) {
    if (position > -1 && position < getItemCount()) {
        return this.mList.get(position);
    } else {
        return null;
    }
}

EDIT 2:

The idea is to set the readCount variable when you instantiate the object. You do not have multiple variables that do the same thing. You just change the single readCount variable to be either 7 or 10 when you are creating it and use the same getItem method when retrieving the model (not variable!) itself.

ModelDoa:

public class ModelDoa {

    private String name;
    private String butong;
    private int type;
    private int readCount;

    public ModelDoa(String name, String butong, int type, int readCount) {
        this.mName = name;
        this.bName = butong;
        this.mType = type;
        this.readCount = readCount;
    }

    public int getReadCount() {
        return this.readCount;
    }

    public void setReadCount(int readCount) {
        this.readCount = readCount;
    }
}

DoaPagi:

private List<ModelDoa> getData() {
    String[] data = getResources().getStringArray(R.array.doapagi);
    String[] baca = getResources().getStringArray(R.array.bacapagi);

    List<ModelDoa> list = new ArrayList<ModelDoa>();

    for (int i = 0; i < data.length; i++) {
        // Here is where you would set the value of readCount.
        list.add(new ModelDoa(data[i], baca[i], ModelDoa.DOA_PAGI, i));
    }

    return list;
}

Here is the fix. just update the ModelDoa constructor as below. I have verified myself and working as expected now. Also sent you pull request on github .

public ModelDoa(String name, String butong, int type) {
    this.mName = name;
    this.bName = butong;
    this.mType = type;
    String[] data = butong.split("\\s");
    if (data.length > 0) {
        String count = data[1].substring(0, data[1].length() - 1);
        read10 = Integer.parseInt(count);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM