Java 从回收器视图中删除条目时出现问题
这个问题快把我逼疯了。到现在为止,我已经尝试了20种不同的方法。让我们看看这里是否有人能帮我 我正在使用Java 从回收器视图中删除条目时出现问题,java,android,firebase,firebase-realtime-database,android-recyclerview,Java,Android,Firebase,Firebase Realtime Database,Android Recyclerview,这个问题快把我逼疯了。到现在为止,我已经尝试了20种不同的方法。让我们看看这里是否有人能帮我 我正在使用RecyclerView制作一个待办事项列表应用程序,该应用程序将数据存储在Firebase中 该应用程序具有一个TasksActivity,其中所有任务都显示在RecyclerView中。我有一个进入任务创建对话框的按钮。我可以创建任务,它们会出现在RecyclerView(任务活动)中,并在firebase中更新,不会出现任何问题。我可以关闭应用程序,稍后再回来,一切正常,当我加载应用程序
RecyclerView
制作一个待办事项列表应用程序,该应用程序将数据存储在Firebase中
该应用程序具有一个TasksActivity
,其中所有任务都显示在RecyclerView
中。我有一个进入任务创建对话框的按钮。我可以创建任务,它们会出现在RecyclerView
(任务活动)中,并在firebase中更新,不会出现任何问题。我可以关闭应用程序,稍后再回来,一切正常,当我加载应用程序时,所有条目都会再次出现在应用程序中。我还可以滑动以删除条目,并且该条目也会从firebase中的数据库中删除
问题是,当我创建一个任务而不关闭应用程序时,我试图删除我刚刚创建的任务。它不允许我那样做。当我创建一个新任务,并在关闭应用程序之前立即删除它时,它会再次出现。但如果我关闭应用程序,然后再次加载,该条目可以正常删除,但如果我在创建条目的同一会话中,则无法删除该条目
我使用了一些Log.d
参数来查看它是如何变化的。由于各种原因,我认为问题在于OnDataChange()
。但到目前为止,我还没有找到问题的根源。这是TaskActivity
类,在此之后,我将粘贴TasksCreation
(我认为没有必要粘贴适配器)
我真的很感激你能告诉我这个问题
非常感谢
p:S:这是TaskAdapter
的代码(忽略dayofweek部分只是我注释的部分代码)
公共类TasksAdapter扩展了RecyclerView.Adapter{//v1.3添加到ClickListener
语境;
数组列表任务;
数据库参考;
SimpleDataFormat sdf=新的SimpleDataFormat(“EEEE”);
日期d=新日期();
最终字符串dayOfWeek=sdf.format(d).substring(0,3);
公共任务适配器(上下文、ArrayList任务){
this.context=上下文;
这个。任务=任务;
}
公共类MyViewHolder扩展了RecyclerView.ViewHolder{//V1.3添加了实现View.OnClickListener
文本视图任务标题;
文本视图任务日期;
文本视图任务描述;
复选框任务复选框;
ConstraintLayout ConstraintLayout;//添加到更改每个RecyclerView项的背景中。
公共MyViewHolder(@NonNull View itemView){
超级(项目视图);
taskTitle=itemView.findViewById(R.id.taskTitle);
taskDate=itemView.findviewbyd(R.id.taskDate);
taskDescription=itemView.findViewById(R.id.taskDescription);
taskCheckBox=itemView.findViewById(R.id.taskCheckBox);
constraintLayout=(constraintLayout)itemviewbyd(R.id.item\u task\u布局);
itemView.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
int pos=getAdapterPosition();
//if(pos!=RecyclerView.NO_POSITION){//检查项目是否仍然存在
TaskItems单击DataItem=tasks.get(pos);
Toast.makeText(v.getContext(),“您单击了”+clickedDataItem.getTaskTitle(),Toast.LENGTH_SHORT).show();
// }
}
});
}
}
@非空
@凌驾
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){//onCreateViewHolder的标准代码
返回新的MyViewHolder(LayoutInflater.from(context).充气(R.layout.item_task,parent,false));
}
@凌驾
public void onBindViewHolder(final@NonNull MyViewHolder,final int position){//对于列表中的每个项,此方法调用一次。
holder.taskTitle.setText(tasks.get(position.getTaskTitle());
holder.tasksdescription.setText(tasks.get(position.getTaskDescription());
holder.taskDate.setText(tasks.get(position.getTaskDate());
holder.taskCheckBox.setChecked(tasks.get(position.isChecked());
holder.taskCheckBox.setTag(tasks.get(position.getKey());
holder.taskCheckBox.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
FirebaseDatabase=FirebaseDatabase.getInstance();
字符串post=(字符串)holder.taskCheckBox.getTag();
Toast.makeText(上下文,“这是复选框编号:”+post,Toast.LENGTH_SHORT).show();//工作正常//更改新逻辑
reference=database.getReference(“MotApp”).child(post);
布尔checkboxStatus=holder.taskCheckBox.isChecked();
Log.d(“Checked”,“onClick:选中的taskcheckbox是”+holder.taskcheckbox.isChecked());
TaskItems值=新TaskItems(tasks.get(position).getKey(),tasks.get(position).getTaskTitle(),tasks.get(position).getTaskDate(),tasks.get(position).getTaskDescription(),checkboxStatus);
参考。设定值(值);
Toast.makeText(上下文,“这是属于项“+tasks.get(position).getTaskTitle(),Toast.LENGTH_LONG).show()的复选框);
}
});
}
@凌驾
public int getItemCount(){//告诉适配器大小。如果为零,则不会创建任何内容
返回任务。size();
}
}
当您从任务创建返回时,需要在任务活动
中重建回收视图
数据;这是因为调用了TasksActivity
的onCreate()
回调
public class TasksActivity extends AppCompatActivity {
DatabaseReference reference;
RecyclerView myTasks;
ArrayList<TaskItems> myTasksList;
TasksAdapter tasksAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks);
myTasks = findViewById(R.id.my_tasks); // RecyclerView that I defined as part of the layout. This is the id of it
myTasks.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
myTasksList = new ArrayList<>();
Button openCreateTask = findViewById(R.id.openCreateTask);
tasksAdapter = new TasksAdapter(this,myTasksList);
myTasks.setAdapter(tasksAdapter);
new ItemTouchHelper(itemTouchHelper).attachToRecyclerView(myTasks);
openCreateTask.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent_task = new Intent(getApplicationContext(), TasksCreation.class);
startActivity(intent_task);
}
});
reference = FirebaseDatabase.getInstance().getReference().child("MotApp"); // Name of the App in the database .child("MotApp")
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // It gets the info from the database
Log.d("data Changed called", "onDataChange: is called");
Log.d("whatever", "onDataChange BEGIN Array of myTasksList size is "+myTasksList.size());
myTasksList.clear(); // Added later to avoid duplication
for(DataSnapshot elements: dataSnapshot.getChildren()){
TaskItems p = elements.getValue(TaskItems.class);
myTasksList.add(p);
}
tasksAdapter.notifyDataSetChanged(); // If this is put outside of onDataChange, it displays a blank list.
Log.d("whatever", "onDataChange END Array of myTasksList size is "+myTasksList.size());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), "No data", Toast.LENGTH_SHORT).show();
}
});
}
ItemTouchHelper.SimpleCallback itemTouchHelper = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {
@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) {
int position = viewHolder.getAdapterPosition();
Log.d("ARRAY SIZE", "onSwiped BEGIN Array of myTasksList size is "+myTasksList.size());
String key = myTasksList.get(position).getKey();
reference= FirebaseDatabase.getInstance().getReference().child("MotApp").child(key);
Toast.makeText(getApplicationContext(),"This is key "+key,Toast.LENGTH_LONG).show();
reference.removeValue();
myTasksList.remove(position);
tasksAdapter.notifyItemRemoved(position);
Log.d("ARRAY SIZE", "onSwiped END Array of myTasksList size is "+myTasksList.size());
}
};
}
public class TasksCreation extends AppCompatActivity {
DatabaseReference referenceCreation;
ArrayList<String> list;
EditText taskName;
EditText taskDescr;
Button selectDates;
TextView taskDate;
Button createTask;
Button cancel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks_creation);
taskName = findViewById(R.id.et_TaskName);
taskDescr = findViewById(R.id.et_TaskDescr);
selectDates = findViewById(R.id.selectDates);
taskDate= findViewById(R.id.tv_Dates);
createTask = findViewById(R.id.createTask);
cancel = findViewById(R.id.cancelButton);
createTask.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!TextUtils.isEmpty(taskName.getText()) && !TextUtils.isEmpty(taskDate.getText())) {
referenceCreation = FirebaseDatabase.getInstance().getReference().child("MotApp").push(); //saves it with custom key created by Firebase
final String key = referenceCreation.getKey();
referenceCreation.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
dataSnapshot.getRef().child("key").setValue(key);
dataSnapshot.getRef().child("taskTitle").setValue(taskName.getText().toString());
dataSnapshot.getRef().child("taskDescription").setValue(taskDescr.getText().toString());
dataSnapshot.getRef().child("taskDate").setValue(taskDate.getText().toString());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Intent intent = new Intent(getApplicationContext(), TasksActivity.class);
startActivity(intent);
} else{
Toast.makeText(getApplicationContext(), "You haven't filled all the fields", Toast.LENGTH_SHORT).show();
}
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), TasksActivity.class);
startActivity(intent);
}
});
selectDates.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createAlertDialogue();
}
});
}
private void createAlertDialogue(){
list = new ArrayList<String>();
AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.MyDialogTheme);
builder.setTitle("Select days");
builder.setMultiChoiceItems(R.array.Days, null, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
String arr[] = getResources().getStringArray(R.array.Days);
if(isChecked){
list.add(arr[which]);
}else if(list.contains(arr[which])){
list.remove(arr[which]);
}
}
});
builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
String data = "";
@Override
public void onClick(DialogInterface dialog, int which) {
for(String elements: list){
elements = elements.substring(0,3);
data= elements+" "+data;
}
taskDate.setText(data);
}
});
builder.create();
builder.show();
}
}
public class TasksAdapter extends RecyclerView.Adapter<TasksAdapter.MyViewHolder> { // V 1.3 added OnClickListener
Context context;
ArrayList<TaskItems> tasks;
DatabaseReference reference;
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Date d = new Date();
final String dayOfTheWeek = sdf.format(d).substring(0,3);
public TasksAdapter(Context context, ArrayList<TaskItems> tasks) {
this.context = context;
this.tasks = tasks;
}
public class MyViewHolder extends RecyclerView.ViewHolder { // V1.3 Added implements View.OnClickListener
TextView taskTitle;
TextView taskDate;
TextView taskDescription;
CheckBox taskCheckBox;
ConstraintLayout constraintLayout; // Added to change background of each RecyclerView item.
public MyViewHolder(@NonNull View itemView) {
super(itemView);
taskTitle = itemView.findViewById(R.id.taskTitle);
taskDate = itemView.findViewById(R.id.taskDate);
taskDescription = itemView.findViewById(R.id.taskDescription);
taskCheckBox = itemView.findViewById(R.id.taskCheckBox);
constraintLayout = (ConstraintLayout) itemView.findViewById(R.id.item_task_layout);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = getAdapterPosition();
// if(pos != RecyclerView.NO_POSITION){//Checks if item still exists
TaskItems clickedDataItem = tasks.get(pos);
Toast.makeText(v.getContext(), "You clicked " + clickedDataItem.getTaskTitle(), Toast.LENGTH_SHORT).show();
// }
}
});
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // standard code for onCreateViewHolder
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_task,parent,false));
}
@Override
public void onBindViewHolder(final @NonNull MyViewHolder holder, final int position) { // This method is called once for each item on the list.
holder.taskTitle.setText(tasks.get(position).getTaskTitle());
holder.taskDescription.setText(tasks.get(position).getTaskDescription());
holder.taskDate.setText(tasks.get(position).getTaskDate());
holder.taskCheckBox.setChecked(tasks.get(position).isChecked());
holder.taskCheckBox.setTag(tasks.get(position).getKey());
holder.taskCheckBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
String post = (String) holder.taskCheckBox.getTag();
Toast.makeText(context,"This is checkbox number: "+post,Toast.LENGTH_SHORT).show(); // Working Well. //change for new logic
reference = database.getReference("MotApp").child(post);
boolean checkboxStatus = holder.taskCheckBox.isChecked();
Log.d("Checked", "onClick: The taskcheckbox checked is "+holder.taskCheckBox.isChecked());
TaskItems value = new TaskItems(tasks.get(position).getKey(),tasks.get(position).getTaskTitle(), tasks.get(position).getTaskDate(),tasks.get(position).getTaskDescription(),checkboxStatus);
reference.setValue(value);
Toast.makeText(context,"This is a checkbox belonging to item "+tasks.get(position).getTaskTitle(),Toast.LENGTH_LONG).show();
}
});
}
@Override
public int getItemCount() { //tells the adapter the size . if it's zero then it won't create anything
return tasks.size();
}
}
public class TasksActivity extends AppCompatActivity {
DatabaseReference reference;
RecyclerView myTasks;
ArrayList<TaskItems> myTasksList;
TasksAdapter tasksAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks);
}
@Override
protected void onResume() {
super.onResume();
myTasks = findViewById(R.id.my_tasks); // RecyclerView that I defined as part of the layout. This is the id of it
myTasks.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
myTasksList = new ArrayList<>();
Button openCreateTask = findViewById(R.id.openCreateTask);
tasksAdapter = new TasksAdapter(this,myTasksList);
myTasks.setAdapter(tasksAdapter);
new ItemTouchHelper(itemTouchHelper).attachToRecyclerView(myTasks);
openCreateTask.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent_task = new Intent(getApplicationContext(), TasksCreation.class);
startActivity(intent_task);
}
});
reference = FirebaseDatabase.getInstance().getReference().child("MotApp"); // Name of the App in the database .child("MotApp")
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) { // It gets the info from the database
Log.d("data Changed called", "onDataChange: is called");
Log.d("whatever", "onDataChange BEGIN Array of myTasksList size is "+myTasksList.size());
myTasksList.clear(); // Added later to avoid duplication
for(DataSnapshot elements: dataSnapshot.getChildren()){
TaskItems p = elements.getValue(TaskItems.class);
myTasksList.add(p);
}
tasksAdapter.notifyDataSetChanged(); // If this is put outside of onDataChange, it displays a blank list.
Log.d("whatever", "onDataChange END Array of myTasksList size is "+myTasksList.size());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), "No data", Toast.LENGTH_SHORT).show();
}
});
}
ItemTouchHelper.SimpleCallback itemTouchHelper = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {
@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) {
int position = viewHolder.getAdapterPosition();
Log.d("ARRAY SIZE", "onSwiped BEGIN Array of myTasksList size is "+myTasksList.size());
String key = myTasksList.get(position).getKey();
reference= FirebaseDatabase.getInstance().getReference().child("MotApp").child(key);
Toast.makeText(getApplicationContext(),"This is key "+key,Toast.LENGTH_LONG).show();
reference.removeValue();
myTasksList.remove(position);
tasksAdapter.notifyItemRemoved(position);
Log.d("ARRAY SIZE", "onSwiped END Array of myTasksList size is "+myTasksList.size());
}
};
}