【问题标题】:How to Delete Item Without Deleting Position in Recycler View?如何在不删除回收站视图中的位置的情况下删除项目?
【发布时间】:2018-08-03 14:40:38
【问题描述】:

我真的需要你的帮助。我用很多关键词在谷歌搜索了很多天,但我无法得到它。所以,我决定问你。

所以,就是这样。实际上,我在 RecyclerView 中有一个按钮,但是这个按钮重复了尽可能多的可用数据,有:带有文本“Baca 3x”、“Baca 4x”等的按钮。我想,如果我单击带有文本“Baca 3x”的按钮 3 次,它将变为“Baca 2x”>>“Baca 1x”>>删除项目。此外,如果我单击带有文本“Baca 4x”的按钮 4 次,它将变为“Baca 3x”>>“Baca 2x”>>“Baca 1x”>>删除项目。

但我的问题是,我不能对每个按钮进行不同的处理,因为每次删除项目时,数据的位置都会自动改变。因此,我无法获得特定的按钮。例如:有两个按钮,

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

如果位置 0 上的按钮“Baca 3x”已被删除,那么按钮“Baca 4x”会自动将其位置更改为 0。问题出在此处。

到目前为止,我只是根据它们的位置来获取每个按钮,这对我来说是个问题。因此,我正在考虑如何在不删除回收站视图中的位置的情况下删除项目?你们能解决我的问题吗?我应该使用 DiffUtil 吗?以及如何使用它?下面是我使用的完整代码:

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);
}

}

更新(修复代码)作者:Krishna Sharma: https://github.com/seadclark/RecyclerViewWithButtonClicks

【问题讨论】:

  • 看看下面的答案,它可能会有所帮助
  • 你在字符串数组String[] baca = getResources().getStringArray(R.array.bacapagi); 中有硬编码的读取计数吗,例如这个字符串数组可能有任何顺序的项目,比如 (1) Baca 5x (2) Baca 2x (3) Baca 10x 等等上?
  • 是的,我做到了。它工作,所有数据列表都可以显示。但这还不够,按钮不工作就用这种方式
  • 我想我明白你的意思了,立即查看更新的答案
  • 我改过了

标签: java android android-recyclerview


【解决方案1】:

这里是修复。只需更新ModelDoa 构造函数,如下所示。我已经验证了自己并按预期工作。 还在 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);
    }
}

【讨论】:

  • 错误:没有找到适合 valueOf(Object) 方法的方法 Integer.valueOf(String) 不适用(参数不匹配;Object 无法转换为 String)方法 Integer.valueOf(int) 不适用(参数不匹配;对象无法转换为 int)
  • 也不行。如果我点击按钮,它将是 -1
  • 如果您单击按钮让我们说 baca 2 x,会发生什么。确保在 onBindViewHolder 中你调用了这个tombolbaca.setTag(""+position);
  • @Sa'adAbdurrazzaq 你试过这个解决方案了吗?请通过单击任何按钮分享观察结果。例如,您开始点击“Baca 2x”
  • 明天我会做的,我会告诉你的。我也会在github上发布这个
【解决方案2】:

有两种方法,而不是从列表中删除项目并更新界面。其中一个(deleteItem)只会删除项目,另一个(deleteItemAndUpdate)会删除项目并更新界面。

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

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

将来,您可以决定是仅从列表中删除该项目还是删除该项目并更新 UI。

编辑 1:

您需要跟踪每个项目被点击的次数。我们可以称这个值为 readCount。每次单击该项目时,我们都会从该值中减去 1。当此值达到 0 时,我们将其从列表中删除。

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;
    }
}

编辑 2:

想法是在实例化对象时设置 readCount 变量。你没有多个变量做同样的事情。您只需在创建时将单个 readCount 变量更改为 7 或 10,并在检索模型(不是变量!)本身时使用相同的 getItem 方法。

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;
}

【讨论】:

  • 我试过 public void deleteItem(int position) { mList.remove(position); // hapus list } 它不能删除项目
  • 什么意思?它没有从列表中删除?你能在你的 deleteItem 方法中添加一个 Log 语句,看看它是否真的被执行了吗?
  • 如果按钮从 10 开始,它将是 9,8,7,6,5,4,3,2,1,0,-1 等等。这是结果
  • 我的意思是实际方法调用的结果。检查我的编辑。
  • 很抱歉打扰您。但我真的需要你的帮助。我在这里呆了很多天。我想向你解释一个真正的问题。 “Baca”是印尼语,在英语中的意思是“Read”。所以,当按钮的文本是“Baca 3x”时,意味着阅读了三遍。我们可以实现三次,点击按钮 3 次,按钮会变成 Baca 2x >> Baca 1x >> remove item 。到这里,你明白了吗?
猜你喜欢
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多