当前位置: 首页 > 面试题库 >

如何同时从recyclerView和sqlite数据库删除行?

澹台啸
2023-03-14
问题内容

我正在使用回收者视图和SQLite数据库创建一个应用程序。当用户输入一些数据时,它会显示在“回收者”视图中,并且还会添加到我的数据库中。现在,我想delete在回收者视图中实现功能。

我想要的是:

我想同时从数据库和回收者视图中删除所需的行,而不会得到任何意外结果。并且所有行均应删除。

我尝试过的

我实现了onLongClickListenercardView回收视图(我使用cardView作为回收鉴于行)。现在,当使用它的长按时,我将获得适配器位置。并删除该位置的数据库条目。

但是,这给了我意想不到的结果,例如:在再次创建回收站视图的活动时,所有在实际删除行以下的删除行或一次删除的行都会再次出现,并且永远不会删除最后2-3行,这是数据库条目已删除。

我的回收站视图适配器代码是:

public class AdapterForMain extends RecyclerView.Adapter<AdapterForMain.ViewHolder>{
ArrayList<String> mDataset;
ArrayList<String> mfooterSet;

private int[] icon;
MainActivity context;
DatabaseHelper myDb;


public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    // each data item is just a string in this case

    public TextView txtHeader;
    public TextView txtFooter;
    public ImageView imgView;
 //   MainActivity mainActivity;

    CardView cardView;

    public ViewHolder(View v) {
        super(v);
        txtHeader = (TextView) v.findViewById(R.id.firstLine);
        txtFooter = (TextView) v.findViewById(R.id.secondLine);
        imgView = (ImageView) v.findViewById(R.id.icon);

        cardView = (CardView)v.findViewById(R.id.cardView);
        cardView.setOnClickListener(this);
        cardView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                myDb = new DatabaseHelper(context);

                int detingPos = getAdapterPosition();
                boolean isDeleted = myDb.deleteEntry(detingPos);

                if(isDeleted){
                    mDataset.remove(getAdapterPosition());
                    notifyItemRemoved(getAdapterPosition());
                    notifyItemRangeChanged(getAdapterPosition(),mDataset.size());

                }
                Toast.makeText(context,"Delete from here",Toast.LENGTH_SHORT).show();

                  return true;
            }
        });
    }

    @Override
    public void onClick(View view) {

       // Toast.makeText(context,Integer.toString(getAdapterPosition()),Toast.LENGTH_SHORT).show();
        context.detailActivity(getAdapterPosition(),mDataset.get(getAdapterPosition()),mfooterSet.get(getAdapterPosition()));
    }
}


// Provide a suitable constructor (depends on the kind of dataset)
public AdapterForMain(ArrayList<String> myDataset, ArrayList<String> myFooterSet, int[] images, MainActivity context0) {
    icon = images;
    mDataset = myDataset;
    mfooterSet = myFooterSet;
    context = context0;
}

// Create new views (invoked by the layout manager)
@Override
public AdapterForMain.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_main, parent, false);
    // set the view's size, margins, paddings and layout parameters
    ViewHolder vh = new ViewHolder(v);

    return vh;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    final String name = mDataset.get(position);
    holder.txtHeader.setText(mDataset.get(position));
    holder.txtHeader.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            //  Toast.makeText(AdapterForMain.this,"Settings Activity is under Construction.",Toast.LENGTH_SHORT).show();
        }
    });

    holder.txtFooter.setText(mfooterSet.get(position));
    holder.imgView.setImageResource(icon[position%1]);
}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataset.size();
}}

delete方法代码:

    public boolean deleteEntry(int row) {
        SQLiteDatabase db=this.getWritableDatabase();
        db.delete(TABLE_NAME, COL_1 + "=" + row,null);
        return true;
    }

问题答案:

首先,您需要传递long给delete方法,而 不是 int。其次,您应该将 确切的rowId 传递给您的方法,而 不是
适配器的位置。因为适配器位置将始终是从0到某个数字的连续数字集,并且之间没有间隔,所以在数据库中,从表中删除数据后,某些数字将不用于rowId。例如,如果您删除第5行,则SQLite
db不再使用索引4。您将拥有0、1、2、3、5、6 …这样的行,因为它是自动递增的。

我建议您将数据存储在二维数组或ArrayList中。然后,COL_1从db检索数据时,也需要将相应的文本也传递给值。这样,您将始终知道哪个行号包含特定数据,并在要删除该行号时显示该行号。

因为只有一列数据,所以很容易为您显示带有二维数组的版本。

您可以将其想象成数组的数组:

mDataset->

在位置:
0 | array1
1 | arrays2
2 | array3

… | …

array1->

在位置:
0 | rowId
1 | textData

array2->

在位置:
0 | rowId
1 | textData

等等。但是您将需要更改用于从db检索数据的方法的代码,以便它将返回上述ArrayList。

代码如下所示:

在您的数据库中:

// getData method
public ArrayList<ArrayList<String>> getData() {
    SQLiteDatabase db=this.getWritableDatabase();
    String[] columns = new String[]{COL_1, COL_2};
    Cursor c = ourDatabase.query(TABLE_NAME, columns, null, null, null, null, null);

    int rowId = c.getColumnIndex(COL_1);
    int text = c.getColumnIndex(COL_2);

    ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();

    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
        ArrayList<String> temp = new ArrayList<String>();
        temp.add(c.getString(rowId));
        temp.add(c.getString(text));
        data.add(temp);
    }

    return data;
}

// deleteEntry method
public boolean deleteEntry(long row) {
    SQLiteDatabase db=this.getWritableDatabase();
    db.delete(TABLE_NAME, COL_1 + "=" + row, null);
    return true;
}

数据集:

ArrayList<ArrayList<String>> mDataSet = //initialize or pass data

然后将其用作:

int position = mDataset.get(getAdapterPosition).get(0);
boolean isDeleted = myDb.deleteEntry(Long.parseLong(position));

要么

long position = mDataset.get(getAdapterPosition).get(0);
boolean isDeleted = myDb.deleteEntry(position);


 类似资料:
  • 附注。我对Sqlite没有太多的经验

  • 我在编码方面是新手,所以我复制粘贴了一些教程的代码,但是当我试图删除“睡眠”列中的所有数据时,出现了这个错误。 Android数据库sqlite。SQLiteException:在“20170128”附近:编译时出现语法错误(代码1)::在android上从20170128删除。数据库sqlite。SQLiteConnection。android上的nativePrepareStatement(本

  • 这是提供用户输入的主活动 } 这是Add_prople类 公共类Add_people扩展AppCompatActivity实现视图。OnClickListener{private EditText name EditText;private EditText ageEditText;private EditText heightEditText;private EditText weightede

  • 我如何删除记录“苹果”(在图片中标记)? 根据文档,要移除一个项,需要对引用调用removeValue()。但要获得引用,我需要子ID。因为它是一个随机生成的id(-kisnx87ayigsh3ilp0d),如何删除它?

  • 我在Android应用程序中使用Firebase实时数据库,数据如下: 如何从javascript访问该数据。我只想编写一个函数来获取每个endTime的值,并和当前时间和if endTime进行比较 事件是固定值。 Indjija、Vojvodina和-KsB2mVkpgQe_fRyFFH4是自动生成的,所以有可能有更多像这两个的值。 我知道如何解决这个问题在Android Studio与Jav

  • 我制作了一个JTable,其中填充了数据库中的数据。它从textfields中获取数据并将其添加到表和数据库中。问题是我有一个删除按钮,我让它从表本身删除选定的行(使用defaultTableModel),但它不会从实际的数据库中删除该数据。当我再次运行该程序时,删除的行再次出现在JTable中。 这可能会变得混乱,但希望有人能找出我错过了什么。帮助将会很感激,但不要,我的时间很少,不能完全大修我