繁体   English   中英

如何使用RecyclerView Adapter在SqliteDatabase中添加和更新数据

[英]How to add & update data in SqliteDatabase by using RecyclerView Adapter

我只是尝试使用RecyclerView创建一个列表,其中每个列表项将包含一个复选框按钮。 因此,当用户单击复选框时,它将替换表列的值,例如列国家获取值“A”,另一方面,取消选中将国家列值从“A”替换为“B”或任何内容。

有人可以帮我这个吗? 关于这个以及使用Recyclable在SQLite数据库中添加数据的其他类似方法的任何建议都将非常有用。

下面我添加了我的代码供您参考,并提前致谢。

我的DatabaseHelper类

    package com.hfad.ressql;

    import android.content.ContentValues;
    import android.content.Context;
    import android.content.Intent;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import com.hfad.ressql.DatabaseContractor.*;

    import java.lang.reflect.Array;
    import java.util.ArrayList;
    import java.util.List;

    public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "workers.db";
    private static final int DATABASE_VERSION =7;

    SQLiteDatabase db;

    public DatabaseHelper( Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
     this.db=db;

     final String SQL_CREATE_TBALE="CREATE TABLE " +  EmployeeDetails.TABLE_NAME + "(" + EmployeeDetails._ID +" INTEGER PRIMARY KEY  AUTOINCREMENT, "+
             EmployeeDetails.COLUMN_FIRSTNAME+" TEXT,  "+EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+EmployeeDetails.COLUMN_COUNTRY+" TEXT)";

     db.execSQL(SQL_CREATE_TBALE);
     fillquestion();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {



        db.execSQL("DROP TABLE IF EXISTS " + EmployeeDetails.TABLE_NAME);
        onCreate(db);

    }


    public void fillquestion(){
    DataModel o4 = new DataModel("Earth","Soil","B");
    IntertData(o4);
    DataModel o5 = new DataModel("Sun","Light","B");
    IntertData(o5);
    DataModel o6 = new DataModel("Moon","Rock","B");
    IntertData(o6);

    }

    public void IntertData (DataModel data){

        ContentValues contentValues = new ContentValues();
        contentValues.put(EmployeeDetails.COLUMN_FIRSTNAME,     data.getFirstName());
        contentValues.put(EmployeeDetails.COLUMN_LASTNAME,   data.getLastName());
        contentValues.put(EmployeeDetails.COLUMN_COUNTRY, data.country);
        db.insert(EmployeeDetails.TABLE_NAME,null,contentValues);
    }

    public List<DataModel> object1() {
        ArrayList<DataModel> details = new ArrayList<DataModel>();
        db = getReadableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + EmployeeDetails.TABLE_NAME, null );
        if (cursor.moveToFirst()) {

            do {
                DataModel object2 = new DataModel();
                object2.setFirstName(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_FIRSTNAME)));
                object2.setLastName(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_LASTNAME)));
                object2.setCountry(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_COUNTRY)));


                details.add(object2);

            } while (cursor.moveToNext());
        }
        cursor.close();
        return details;
    }
}

这是我的DataModel类

    package com.hfad.ressql;

    public class DataModel {

    public String FirstName;
    public String LastName;
    public String country;



    public DataModel() {
    }

    public DataModel(String firstName, String lastName, String country) {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.country = country;
    }

    public String getFirstName() {
        return FirstName;
    }

    public void setFirstName(String firstName) {
        FirstName = firstName;
    }

    public String getLastName() {
        return LastName;
    }

    public void setLastName(String lastName) {
        LastName = lastName;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
     }

数据库构造函数

       public final class DatabaseContractor {

       private DatabaseContractor (){}

        public static class EmployeeDetails implements BaseColumns {
        public static final String TABLE_NAME="employy";
        public static final String COLUMN_FIRSTNAME="First_Name";
        public static final String COLUMN_LASTNAME="Last_Name";
        public static final String COLUMN_COUNTRY="Country";
        public static final String COLUMN_FAVO="mfav";


        }

        }

Recycler适配器

在这里,我正在努力解决它。 我需要的是,如果我点击复选框,将在数据库中更新一个预先给定的值,同时将检查复选框,直到用户取消选中它。 当用户取消选中它时,数据库将用新值替换先前的值。 实际上,我只是尝试在表列中包含值,以便我可以将其用作收藏夹或书签列表。

    public class RecycAdapter extends       
    RecyclerView.Adapter<RecycAdapter.ViewHolder> {

    List<DataModel> dotamodeldataArraylist;
    Context context;
    SQLiteDatabase db;
    DatabaseHelper helper;
    ContentValues contentValues;
    Cursor cursor;

    public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
        this.dotamodeldataArraylist=dotamodeldataArraylist;
        this.context=context;
    }

    @Override
    public ViewHolder onCreateViewHolder( ViewGroup parent, int ViewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {

        DataModel obj3= dotamodeldataArraylist.get(position);
        holder.Fnam.setText(obj3.getFirstName());
        holder.Lname.setText(obj3.getLastName());
        holder.Country.setText(obj3.getCountry());
        holder.fav.();
      holder.fav.setChecked(fav);
      final int currentPosition = position;



           final boolean fav = 0==0;
      holder.fav.setChecked(fav);
      final int currentPosition = position;



        holder.fav.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                if(holder.fav.isChecked()){
                   try {
                       contentValues = new ContentValues();
                       contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, "B");
                       db.update("DRINK", contentValues, "id_=?", new String[]{Integer.toString(currentPosition)});
                   } catch (SQLException e){
                       Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();

                   }

                    Toast.makeText(context,"checked " + position , Toast.LENGTH_LONG).show();

                } if(!holder.fav.isChecked()){
                    Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
                }



            }
        });






    }

    @Override
    public int getItemCount() {
        return dotamodeldataArraylist.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView Fnam,Lname,Country;
        CheckBox fav;
        RelativeLayout relativeLayout;


        public ViewHolder(View itemView) {
            super(itemView);

            Fnam = itemView.findViewById(R.id.name1);
            Lname = itemView.findViewById(R.id.city1);
            Country = itemView.findViewById(R.id.country1);
            fav=itemView.findViewById(R.id.chk);
            relativeLayout = (RelativeLayout)     itemView.findViewById(R.id.layout);

        }
    }


    }

查看课程

查看所有课程

    public class Viewall extends AppCompatActivity {

    RecyclerView recyclerView;
    DatabaseHelper databaseHelper;
    RecycAdapter recycAdapter;
    List<DataModel> dotamodeldataArraylist;
    Context context;
    Button show;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewall);

        show = findViewById(R.id.view);
        recyclerView=findViewById(R.id.recycle);

        databaseHelper =new DatabaseHelper(this);
        dotamodeldataArraylist = new ArrayList<DataModel>();
        dotamodeldataArraylist=databaseHelper.object1();
        recycAdapter =new RecycAdapter(dotamodeldataArraylist,this);
        RecyclerView.LayoutManager reLayoutManager =new            
        LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(reLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(recycAdapter);

我相信以下内容可以按照您的意愿行事。

代码中存在很多问题。 其中一个主要问题是您希望该位置与id (即您的_id列)相关联。

列表中第一项的位置为0 ,除非您强制/专门设置值0, rowid列的别名(您的_id列是rowid列的别名),分配的第一个值将为1,然后可能2,然后可能3 ...........

所以最好的位置将比id低1。

如果删除了一行,除了最后一行之外,那么位置将减去一个,除非直到删除的行被传递,然后位置将比rowid小2。 位置和id之间的更多删除和更复杂的相关性。 我想有人可以提出一个傻瓜证明转换,但简单的方法是确保DataModel具有相应_id列的值。

因此,应该更改DataModel.java以包含id的成员/变量,因此使用了以下内容: -

public class DataModel {

    public String FirstName;
    public String LastName;
    public String country;

    public long id; //<<<<<<<<<< ADDED also added gettter and setter

    public DataModel() {
    }

    public DataModel(String firstName, String lastName, String country) {
        this(firstName,lastName,country,-1);
    }

    //<<<<<<<<<< ADDED so ID can be set
    public DataModel(String firstName, String lastName, String country, long id) {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.country = country;
        this.id = id;
    }

    public String getFirstName() {
        return FirstName;
    }

    public void setFirstName(String firstName) {
        FirstName = firstName;
    }

    public String getLastName() {
        return LastName;
    }

    public void setLastName(String lastName) {
        LastName = lastName;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public void setId(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }
}
  • 查看有关更改的注释

当您需要从数据库中提取id时,在DatabaseHelper.java中更改了object1方法(还进行了一些其他更改),使用了以下内容: -

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "workers.db";
    private static final int DATABASE_VERSION =7;

    SQLiteDatabase db;

    public DatabaseHelper( Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        db = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        this.db=db; //<<<<<<< WRONG PLACE as onCreate only ever runs when there is no database

        final String SQL_CREATE_TBALE="CREATE TABLE " +  DatabaseContractor.EmployeeDetails.TABLE_NAME + "(" + DatabaseContractor.EmployeeDetails._ID +" INTEGER PRIMARY KEY  AUTOINCREMENT, "+
                DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME+" TEXT,  "+ DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY+" TEXT)";

        db.execSQL(SQL_CREATE_TBALE);
        fillquestion();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + DatabaseContractor.EmployeeDetails.TABLE_NAME);
        onCreate(db);
    }


    public void fillquestion(){
        IntertData(new DataModel("Earth","Soil","B"));
        IntertData(new DataModel("Sun","Light","B"));
        IntertData(new DataModel("Moon","Rock","B"));
    }

    public void IntertData (DataModel data){

        ContentValues contentValues = new ContentValues();
        contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME,data.getFirstName());
        contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME,data.getLastName());
        contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY,data.country);
        db.insert(DatabaseContractor.EmployeeDetails.TABLE_NAME,null,contentValues);
    }

    public List<DataModel> object1() {
        ArrayList<DataModel> details = new ArrayList<>();
        //db = getReadableDatabase(); db has already been set when database was instantiated/constructed
        Cursor cursor = db.rawQuery("SELECT * FROM " + DatabaseContractor.EmployeeDetails.TABLE_NAME, null );
        while (cursor.moveToNext()) {
            details.add(new DataModel(
                    cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME)),
                    cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME)),
                    cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY)),
                    cursor.getLong(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails._ID)) //<<<<<<<<< Added so id is available
            ));
        }
        cursor.close();
        return details;
    }
}

对RecycAdapter.java做了相当广泛的修改,使用了以下内容: -

public class RecycAdapter extends RecyclerView.Adapter<RecycAdapter.ViewHolder> {

    List<DataModel> dotamodeldataArraylist;
    Context context;
    SQLiteDatabase db;
    DatabaseHelper helper;
    ContentValues contentValues;

    public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
        this.dotamodeldataArraylist=dotamodeldataArraylist;
        this.context=context;
        helper = new DatabaseHelper(context);
        db = helper.getWritableDatabase();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int ViewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {

        //DataModel obj3= dotamodeldataArraylist.get(position); //<<<<<<<<<< NOT NEEDED
        holder.Fnam.setText(dotamodeldataArraylist.get(position).getFirstName());
        holder.Lname.setText(dotamodeldataArraylist.get(position).getLastName());
        holder.Country.setText(dotamodeldataArraylist.get(position).getCountry());
        holder.fav.setChecked(false); //<<<<<<<<< not stored so initially set to false

        holder.fav.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String newcountry = "B";
                if(holder.fav.isChecked()){
                    if (dotamodeldataArraylist.get(position).getCountry().equals("B")) {
                        newcountry  = "A";
                    }
                    contentValues = new ContentValues();
                    contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, newcountry);
                    if (db.update(
                            DatabaseContractor.EmployeeDetails.TABLE_NAME,
                            contentValues,
                            DatabaseContractor.EmployeeDetails._ID +"=?",
                            new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())}
                            ) > 0) {
                        dotamodeldataArraylist.get(position).setCountry(newcountry);
                        notifyItemChanged(position);
                        Toast.makeText(context,
                                "checked and updated " +
                                        position+ dotamodeldataArraylist.get(position).getFirstName() +
                                        " ID is " + String.valueOf(dotamodeldataArraylist.get(position).getId()),
                                Toast.LENGTH_LONG
                        ).show();
                    } else {
                        Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();
                    }
                } else {
                    Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return dotamodeldataArraylist.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView Fnam,Lname,Country;
        CheckBox fav;

        public ViewHolder(View itemView) {
            super(itemView);
            Fnam = itemView.findViewById(R.id.name1);
            Lname = itemView.findViewById(R.id.city1);
            Country = itemView.findViewById(R.id.country1);
            fav = itemView.findViewById(R.id.chk);
        }
    }
}

最后对Viewall.java进行了一些小的改动,使用了以下内容: -

public class Viewall extends AppCompatActivity {

    RecyclerView recyclerView;
    DatabaseHelper databaseHelper;
    RecycAdapter recycAdapter;
    List<DataModel> dotamodeldataArraylist;
    Button show;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewall);

        show = findViewById(R.id.view);
        recyclerView = findViewById(R.id.recycle);

        databaseHelper = new DatabaseHelper(this);
        dotamodeldataArraylist = databaseHelper.object1();
        recycAdapter = new RecycAdapter(dotamodeldataArraylist, this);
        RecyclerView.LayoutManager reLayoutManager = new
                LinearLayoutManager(this);
        recyclerView.setLayoutManager(reLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(recycAdapter);
    }
}

结果

请注意布局可能不同,但您的应该可能会工作并相应地更改演示文稿

首次运行时: -

在此输入图像描述

单击Sun的复选框后

在此输入图像描述

再次单击并返回到B国,依此类推。

  • 请注意,复选框没有翻转,这是一个问题,正确显示更改的数据(国家/地区)使用notifyItemChanged,它将重新处理列表,从而将复选框设置为false。 您需要将复选框值存储在某处(简而言之,您应该以这种方式使用复选框)。

关闭应用程序并重新启动会保留所做的更改,从而确认已对数据库进行了更改。

在@ MiKe的代码之上,我刚刚在onClickListener中的RecyclerAdapter中进行了一些更改以保存复选框Status并在dataModel类中添加了isChecked作为布尔值 现在它的工作完美。

   holder.chkbox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                Values = new ContentValues();
                Values.put(DatabaseContractor.EmployeeDetails.COLUMN_FAVORITE,holder.chkbox.isChecked());
                try{ db.update(DatabaseContractor.EmployeeDetails.TABLE_NAME,
                        Values,
                        DatabaseContractor.EmployeeDetails._ID + "=?",
                        new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())});

                } catch (SQLException e){
                    Toast.makeText(context,"Error"+position,Toast.LENGTH_LONG).show();
                }
        }
    });

再次感谢迈克为您的精彩指南。 现在,我可以直接在sqlite数据库中保存复选框状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM