删除房间内数据库

Posted

技术标签:

【中文标题】删除房间内数据库【英文标题】:Deleting In Room Database 【发布时间】:2020-05-20 16:57:02 【问题描述】:

我正在学习房间数据库!! 我知道如何从房间数据库中插入和检索数据到回收站视图!但在删除操作中,我收到“没有附加适配器跳过布局!”的错误!

当有人点击回收站视图上的删除按钮时我想要什么。任务应该被删除

这就是为什么我也在Interface中使用delete方法并在Recycler View Adapter中添加Interface,这会回调MainActivity以便我们删除和更新recycler视图

我所有的代码都在下面给出

这是我命名为任务的实体类

@Entity
public class Task implements Serializable 
    @PrimaryKey(autoGenerate =  true)
    private int id;
    @ColumnInfo(name = "task_name")
    private String task_name;
    @ColumnInfo
    private String task_desc;
    @ColumnInfo
    private String comment;

    @ColumnInfo
    private String task_comp_date;
    @ColumnInfo
    private String activate;



    public int getId() 
        return id;
    

    public void setId(int id) 
        this.id = id;
    

    public String getTask_name() 
        return task_name;
    

    public void setTask_name(String task_name) 
        this.task_name = task_name;
    

    public String getTask_desc() 
        return task_desc;
    

    public void setTask_desc(String task_desc) 
        this.task_desc = task_desc;
    

    public String getTask_comp_date() 
        return task_comp_date;
    

    public void setTask_comp_date(String task_comp_date) 
        this.task_comp_date = task_comp_date;
    

    public String getComment() 
        return comment;
    

    public void setComment(String comment) 
        this.comment = comment;
    

    public String getActivate() 
        return activate;
    

    public void setActivate(String activate) 
        this.activate = activate;
    



我的名为 TaskDao 的数据访问对象

@Dao
public interface TaskDao 
    @Query("SELECT * FROM task")
    List<Task> getAll();
    @Insert
    void insert(Task task);
    @Delete
    void delete(Task task);
    @Update
    void update(Task task);

我的数据库

@Database(entities = Task.class,version = 1)
public abstract class AppDataBase extends RoomDatabase 
    public abstract TaskDao taskDao();



我的DataBaseClient 命名为DatabaseClient

public class DatabaseClient 
    private Context context;
    private static DatabaseClient mInstace;

    private AppDataBase appDataBase;

    public DatabaseClient(Context context) 
        this.context = context;
        appDataBase = Room.databaseBuilder(context,AppDataBase.class,"MyDailyTask").build();
    
    public static synchronized DatabaseClient getInstance(Context context)
    
        if(mInstace == null)
        
            mInstace = new DatabaseClient(context);
        
        return mInstace;
    
    public AppDataBase getAppDataBase()
    
        return appDataBase;
    

我的 RecyclerView 适配器

        public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.MyViewHolder> 
private Context context;
private List<Task> taskList;
public interface OnDeleteClickListener
    
        void OnDeleteClickListener(Task task);
    
    private OnDeleteClickListener onDeleteClickListener;

    public TaskAdapter(Context context, List<Task> taskList) 
        this.context = context;
        this.taskList = taskList;
    

    public void setOnDeleteClickListener(OnDeleteClickListener onDeleteClickListener) 
        this.onDeleteClickListener = onDeleteClickListener;
    

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View view;
       view = LayoutInflater.from(context).inflate(R.layout.view_task_list,parent,false);
       MyViewHolder myViewHolder = new MyViewHolder(view);
       return myViewHolder;
    

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) 
       holder.setData(taskList.get(position).getTask_name(),taskList.get(position).getTask_desc(),taskList.get(position).getComment(),taskList.get(position).getTask_comp_date(),position);
    

    @Override
    public int getItemCount() 
        return taskList.size();
    

    class MyViewHolder extends RecyclerView.ViewHolder 

        private TextView t1,t2,t3,t4,t5;
        private ImageView view;
        public MyViewHolder(@NonNull View itemView) 
            super(itemView);
            t1= itemView.findViewById(R.id.tvCommnt);
            t2=itemView.findViewById(R.id.tvDesc);
            t3=itemView.findViewById(R.id.tvName);
            t4= itemView.findViewById(R.id.tvStart);
            t5 = itemView.findViewById(R.id.tvEnd);
            view =itemView.findViewById(R.id.tvdele);


        
        public void  setData(String t01, String t02, String t03, String t05, final int position)
        
            t1.setText("Task Comment               "+t03);
            t2.setText("Task Description           "+t02);
            t3.setText("Task Name                    "+ t01);
            t4.setText("Start  ");
            t5.setText("Ënd    "+t05);
            view.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    if(onDeleteClickListener!=null)
                    
                        onDeleteClickListener.OnDeleteClickListener(taskList.get(position));
                        taskList.remove(position);
                        notifyDataSetChanged();
                    
                
            );

        
    

MainActivity.java:

  public class MainActivity extends AppCompatActivity 

       private RecyclerView recyclerView;
       ImageView imageView;
       @Override
       protected void onCreate(Bundle savedInstanceState) 
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
           imageView = findViewById(R.id.ivAdd);
           recyclerView = findViewById(R.id.rvTask);
           imageView.setOnClickListener(new View.OnClickListener() 
               @Override
               public void onClick(View v) 
                   startActivity(new Intent(getApplicationContext(), AddTaskActivity.class));
               
           );
           new newTask().execute();
       

class newTask extends AsyncTask<Void,Void, List<Task>> implements TaskAdapter.OnDeleteClickListener 
    List<Task> tasks;
    @Override
    protected List<Task> doInBackground(Void... voids) 

         tasks = DatabaseClient.getInstance(getApplicationContext()).getAppDataBase().taskDao().getAll();

        return  tasks;
    

    @Override
    protected void onPostExecute(List<Task> tasks) 
        super.onPostExecute(tasks);
        TaskAdapter taskAdapter = new TaskAdapter(MainActivity.this,tasks);
        LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(),DividerItemDecoration.VERTICAL));
        recyclerView.setAdapter(taskAdapter);
        taskAdapter.setOnDeleteClickListener(this);

    

    @Override
    public void OnDeleteClickListener(final Task task) 
new Handler().postDelayed(new Runnable() 
    @Override
    public void run() 
        DatabaseClient.getInstance(getApplicationContext()).getAppDataBase().taskDao().delete(task);

    
,1000);

        
    

【问题讨论】:

【参考方案1】:

欢迎加入栈

您的接口已声明但未分配,因此当单击列表中的项目时您将抛出空指针,但请在触发方法接口之前检查空指针

首先在你的适配器

中为OnDeleteClickListener添加setter
public void setOnDeleteClickListener(OnDeleteClickListener listener)
 this.onDeleteClickListener=listener;

并且还添加了当用户单击项目时从列表中删除项目的代码 所以在setData方法里面更新这段代码

    view.setOnClickListener(new View.OnClickListener() 
    @Override
    public void onClick(View v) 
        if (onDeleteClickListener != null) 
            onDeleteClickListener.OnDeleteClickListener(taskList.get(position));
            //remove item from list and then notify adapter data is changed
            taskList.remove(position);
            notifyDataSetChanged();
        
    
);

终于在你的AsyncTask 中触发onDeleteClickListener 在此处更新您的代码

@Override
 protected void onPostExecute(List < Task > tasks) 
     super.onPostExecute(tasks);
     TaskAdapter taskAdapter = new TaskAdapter(MainActivity.this, tasks, this);
     LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
     recyclerView.setLayoutManager(layoutManager);
     recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL));
     recyclerView.setAdapter(taskAdapter);

     //pass this that refer to my interface 
     taskAdapter.setOnDeleteClickListener(this);


 

在您的 OnDelete 中,只需使用此代码在另一个线程中运行

AsyncTask.execute(new Runnable() 
    @Override
    public void run() 
        DatabaseClient.getInstance(getApplicationContext()).getAppDataBase().taskDao().delete(task);

    
);

建议:不要将变量或参数命名为 String t01,String t02..etc ,选择这个变量 jop 的名字 比如 String taskComment,String taskName ..etc

希望对你有帮助

【讨论】:

非常感谢 @PiyushJaiswal 欢迎您,如果对您有帮助,请让我的回答正确并投票 我也使用构造函数设置值 但是它是如何从房间数据库中删除的 将任务从 OnDeleteClickListener 传递给 DeleteTask

以上是关于删除房间内数据库的主要内容,如果未能解决你的问题,请参考以下文章

房间持久性库。删除所有

回收站视图仅在我从房间数据库中删除后重新打开活动时更新

检查日期范围内所选房间的可用性

将回收站视图数据中的 onMove() 更改更新到房间数据库

Socket.IO 在一个房间内多次发射(与 React.js 一起使用)

在基于文本的游戏中,如何将对象放置在房间内?