【问题标题】:Undo deleted item from RecyclerView and Firebase从 RecyclerView 和 Firebase 撤消已删除的项目
【发布时间】:2021-04-10 08:20:36
【问题描述】:

从实时数据库和 RecyclerView 中删除项目后,我希望添加一个 UNDO 功能来恢复刚刚删除的项目。我可以知道如何实现吗?

下面是我在适配器类中的源代码:

公共适配器(@NonNull FirebaseRecyclerOptions 选项){ 超级(选项); }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate
                (R.layout.retrieved_layout,parent,false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position, @NonNull Model model) {
        holder.name.setText(model.getTask());
        holder.date.setText(model.getDate());
    }


    public static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name = itemView.findViewById(R.id.taskTv);
        TextView date = itemView.findViewById(R.id.dateTv);

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }

这是我的 MainActivity:

 recyclerView = findViewById(R.id.recyclerview);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setReverseLayout(true);
    linearLayoutManager.setStackFromEnd(true);

    loader = new ProgressDialog(this);
    mAuth = FirebaseAuth.getInstance();
    onlineUserID = mAuth.getCurrentUser().getUid();
    reference = FirebaseDatabase.getInstance().getReference().child("task").child(onlineUserID);

    add = findViewById(R.id.add);
    add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addTask();
        }
    });

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);

    // add task to recycler view
    FirebaseRecyclerOptions<Model> options = new FirebaseRecyclerOptions.Builder<Model>()
            .setQuery(reference, Model.class)
            .build();
    adapter = new Adapter(options);
}

// add task to real time database
private void addTask() {
    AlertDialog.Builder myDialog = new AlertDialog.Builder(this);
    LayoutInflater inflater = LayoutInflater.from(this);

    View view = inflater.inflate(R.layout.input, null);
    myDialog.setView(view);
    AlertDialog dialog = myDialog.create();

    final EditText task = view.findViewById(R.id.taskName);
    ImageView upload = view.findViewById(R.id.upload);

    upload.setOnClickListener((v) -> {
        String mTask = task.getText().toString().trim();
        String id = reference.push().getKey();
        String date = DateFormat.getDateInstance().format(new Date());

        if(TextUtils.isEmpty(mTask)){
            task.setError("Task name required");
            return;
        }
        else {
            loader.setMessage("Adding your data");
            loader.setCanceledOnTouchOutside(false);
            loader.show();

            Model model = new Model(mTask,id,date);
            reference.child(id).setValue(model).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if(task.isSuccessful()) {
                        Toast.makeText(MainActivity.this, "Task added successfully !", Toast.LENGTH_SHORT).show();
                        loader.dismiss();
                    }
                }
            });
        }
        dialog.dismiss();
    });
    dialog.show();
}

// add task to recycler view
@Override
protected void onStart() {
    super.onStart();
    recyclerView.setAdapter(adapter);
    adapter.startListening();
}

// swipe to delete task
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        if (direction == ItemTouchHelper.LEFT) {
            reference.child(key).removeValue();
            Snackbar.make(recyclerView,"Task deleted", Snackbar.LENGTH_SHORT)
                    .setAction("Undo", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {

                        }
                    })
         .show();
        }
    }

【问题讨论】:

    标签: java android firebase firebase-realtime-database android-recyclerview


    【解决方案1】:

    @Eyosiyas 的回答会起作用,但它有一个缺点。如果您想获取属性“isActive”保持值为 true 的节点的所有子节点,它将完全正常工作。但是,如果您需要添加另一个过滤器,例如根据“时间”属性过滤数据,这将不起作用,因为the Firebase Realtime Database does not support queries on multiple properties

    你有什么选择?

    您可以执行删除操作,如果用户单击“撤消”按钮,则将数据写回。这不是最好的解决方案,因为它意味着删除操作后跟写操作。或者你可以模拟删除操作。如何?当用户点击删除按钮时,不要执行实际的删除操作。等着看用户是否点击了“UNDO”。如果用户点击“UNDO”,则不要删除任何内容,否则,删除该元素。

    【讨论】:

    • 如果您认为我的回答对未来的 Firebase 开发者也有帮助,也请考虑投上一票(▲)。我真的很感激。谢谢!
    【解决方案2】:

    如果你从实时数据库中删除它,那么它就消失了。 如果你想实现撤销功能,我建议你创建另一个值isActive。 然后,当用户删除时,您只需将 isActive 更改为 false 并且不显示该数据。 如果用户想要返回数据,您只需将 isActive 更改为 true 即可返回数据。

    所以整个过程是您实际上并没有删除数据,而是将其停用。

    【讨论】:

      【解决方案3】:

      Eyosiyas 的回答是正确的,但是您可以在撤消选项不再可用后删除该项目。假设您的数据模型中有一个名为“已删除”的字段,当用户删除该项目时,您将其设置为 true。此时,数据库中的所有选择都应排除标记为已删除的项目。我注意到您显示了一个带有撤消操作的 SnackBar。单击撤消时,您应该将已删除设置回 false,并且当 SnackBar 被解除时,您实际上可以从数据库中删除项目(因为用户无法在没有 SnackBar 及其操作可用的情况下重做删除)。

      // Set 'deleted' to true in database
      snackbar = Snackbar.make(
          binding.root,
          getString(R.string.item_deleted),
          Snackbar.LENGTH_LONG
      ).setAction(getString(R.string.undo)) {
          // Set 'deleted' back to false in database
      }.addCallback(object : Snackbar.Callback() {
          override fun onDismissed(transientBottomBar: Snackbar, event: Int) {
              if (event != DISMISS_EVENT_ACTION)
                  // Delete item from database
          }
      }).setDuration(5000)
      snackbar.show()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多