【问题标题】:Swipe to delete not working most of the time, it removes data from View but not from SQLite Database滑动删除大部分时间不起作用,它会从视图中删除数据,但不会从 SQLite 数据库中删除
【发布时间】:2018-02-17 16:52:29
【问题描述】:

我是一名初学者。我的应用程序中有一个 SQLite 数据库。我已成功为其添加了添加、删除和更新功能。我现在正在尝试实现滑动删除,但是,我面临当前的问题:有时在我滑动并删除项目后,它被成功删除(从数据库中),有时它没有,有时它删除了上面的项目,有时它上面的项目是 2 个 id。我做了很多试验和错误,但我无法确认为什么会发生这种情况。 总是发生的是该项目从视图中删除,因为它不再有自己的卡片(我正在使用带有 recyclerview 的卡片视图)。

这是相关代码(如果我没有发布任何重要代码,请告诉我,我试图简化这个):

MainActivity.java(这是 recyclerview 显示卡片的地方)

RecyclerView rv;
MyAdapter adapter;
ArrayList < Player > players = new ArrayList < > ();
int posToDelete;
DBAdapter db = new DBAdapter(this);

//SWIPE TO DELETE
ItemTouchHelper.SimpleCallback simpleItemTouchCallback =
    new ItemTouchHelper.SimpleCallback(0,
        ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(RecyclerView recyclerView,
            RecyclerView.ViewHolder viewHolder,
            RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

            int position = viewHolder.getAdapterPosition();
            players.remove(position);
            posToDelete = (position);

            delete(position);
            adapter.notifyDataSetChanged();
        }
    };

//recycler
rv = (RecyclerView) findViewById(R.id.myRecycler);


rv.setLayoutManager(new LinearLayoutManager(this));
rv.setItemAnimator(new DefaultItemAnimator());
rv.hasFixedSize();

ItemTouchHelper itemTouchHelper = new
ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(rv);

//DELETE METHOD
public void delete(int id) {
    db.openDB();
    long result = db.Delete(id + 1);

    if (result > 0) {
        //Deleted toast appears but it doesn't get removed from database?
        Toast.makeText(MainActivity.this, "Deleted",
            Toast.LENGTH_SHORT).show();

    } else {
        Toast.makeText(MainActivity.this, "Error",
            Toast.LENGTH_SHORT).show();
    }

    db.close();
}

DBAdapter.java

Context c;
SQLiteDatabase db;
DBHelper helper;

public DBAdapter(Context ctx)
{
    this.c=ctx;
    helper=new DBHelper(c);
}

//OPEN DB
public DBAdapter openDB()
{
    try
    {
        db=helper.getWritableDatabase();
    }catch (SQLException e)
    {
        e.printStackTrace();
    }

    return this;
}

//CLOSE DB
public void close()
{
    try
    {
        helper.close();
    }catch (SQLException e)
    {
        e.printStackTrace();
    }

}

//DELETE FROM DATABASE <---------
public long Delete(int id)
{
    try
    {
        return db.delete(Constants.TB_NAME,Constants.ROW_ID+" =?",new 
String[]{String.valueOf(id)});

    }catch (SQLException e)
    {
        e.printStackTrace();
    }


    return 0;
}

作为一个附带问题,在调试以查找问题时,我注意到在成功从数据库中删除一个对象后(使用一直有效的删除功能,而不是滑动删除),数据库只是留下那个 id 点空的。因此,例如,如果我有对象 1、2、3、4、5 和 6,当我删除 5 并创建新对象 A 和 B 时,数据库似乎将它们存储为 1、2、3、4,(这里没有),6,A,B。

这是个问题吗?会不会有什么不好的后果?还是这完全正常?

谢谢。

****EDIT**** 你们是对的,传递给delete() 方法的位置不是对象的ID,谢谢指出。

我尝试使用ViewHolder.getItemId() 方法,但它返回long。我尝试将其转换为 integer 并将整个方法参数更改为接受 long 而不是 integer 但我总是得到的 id 值是 -1,这并没有解决任何问题。

在应用程序的其他地方,我使用 onClickListener 获取项目的 ID,因为它将 intent 发送到另一个活动。我在想也许我可以在没有任何用户交互的情况下以其他方式获得 ID?因为当用户滑动删除时,我真的不能等待onClickListener 触发。

【问题讨论】:

    标签: android sqlite android-recyclerview swipe


    【解决方案1】:

    您是否检查过传递给您的 DBAdapter 的 id?

    您似乎是根据适配器位置从数据库中删除项目,可能是数据库中项目的这些 ID 与适配器位置不匹配?

    我之前已经完成了这个滑动删除功能,我很确定我使用了项目 id,例如从你的 ArrayList of Players 中删除了基于数据库中的项目。

    【讨论】:

      【解决方案2】:

      感谢上面的评论,我发现错误在这里: @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

              int position = viewHolder.getAdapterPosition();
              players.remove(position);
              posToDelete = (position);
      
              delete(position);
              adapter.notifyDataSetChanged();
          }
      

      我通过创建一个新变量并将该位置的 id 存储在变量中来解决此问题,然后将新变量传递给 delete 方法,如下所示:

                              int position = viewHolder.getAdapterPosition();
                              int checkingId;
                              checkingId = players.get(position).getId();
                              players.remove(position);
                              delete(checkingId);
                              adapter.notifyDataSetChanged();
                          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-26
        • 2017-12-05
        相关资源
        最近更新 更多